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_SOCKETS_H
17 #define FILLP_SOCKETS_H
18 #include "opt.h"
19 #include "queue.h"
20 #include "epoll.h"
21 #include "hlist.h"
22 #include "net.h"
23
24 #ifdef FILLP_LINUX
25 #include <errno.h>
26 #elif defined(FILLP_WIN32)
27 #include <Winsock2.h>
28 #endif
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 enum SockAllockState {
35 SOCK_ALLOC_STATE_FREE,
36 SOCK_ALLOC_STATE_ERR,
37
38 SOCK_ALLOC_STATE_WAIT_TO_CLOSE, /* app has called SockClose */
39 SOCK_ALLOC_STATE_COMM,
40 SOCK_ALLOC_STATE_EPOLL,
41 SOCK_ALLOC_STATE_EPOLL_TO_CLOSE
42 };
43
44 struct GlobalAppUdpRes {
45 FILLP_UINT32 txBurst; /* max pkt number to send each cycle */
46 #ifdef FILLP_64BIT_ALIGN
47 FILLP_UINT32 reserve;
48 #endif
49 };
50
51 struct GlobalAppCommon {
52 FILLP_UINT32 keepAliveTime; /* ms */
53 FILLP_UINT32 maxServerAllowSendCache;
54 FILLP_UINT32 maxServerAllowRecvCache;
55 FILLP_UINT32 udpSendBufSize;
56 FILLP_UINT32 recvBufSize;
57 FILLP_UINT32 disconnectRetryTimeout; /* Testability addition in the code it is 100. */
58 FILLP_UINT32 sendCache; /* size of send cache */
59 FILLP_UINT32 recvCache; /* size of recv cache */
60 FILLP_UINT32 connectTimeout; /* seconds */
61 FILLP_UINT16 reserve; /* Now not used, need to remove it */
62 FILLP_UINT16 connRetryTimeout; /* Testability addition in the code it is 10. */
63 FILLP_BOOL enableNackDelay;
64 FILLP_BOOL enlargePackIntervalFlag;
65 FILLP_BOOL enableDateOptTimestamp;
66 FILLP_UCHAR pad[3];
67 FILLP_LLONG nackDelayTimeout;
68 FILLP_UINT32 fcStasticsInterval;
69 };
70
71 struct GlobalAppFlowControl {
72 FILLP_UINT32 maxRate; /* maximum data sending rate */
73 FILLP_UINT32 maxRecvRate;
74 FILLP_UINT32 oppositeSetRate; /* Only for Server */
75 FILLP_UINT32 packInterval; /* us */
76 FILLP_UINT16 pktSize; /* default pkt size to cal flow rate */
77 FILLP_BOOL slowStart;
78 FILLP_BOOL constRateEnbale;
79 FILLP_UCHAR reserve[4];
80 };
81
82 struct GlobalAppResource {
83 struct GlobalAppUdpRes udp;
84 struct GlobalAppCommon common;
85 struct GlobalAppFlowControl flowControl;
86 };
87
88 #define MAX_SPUNGE_TYPE_NUM 24 /* Check with SpungeMsgType it shopuld be more than max elements in this enum */
89
90 struct FtSocket {
91 FILLP_INT index; /* index of table */
92 FILLP_INT allocState; /* socket has been allocState */
93 struct FtNetconn *netconn;
94 /* These following members are used for connection and referenced by FtNetconn */
95 FILLP_INT coreErrType[MAX_SPUNGE_TYPE_NUM];
96
97 struct HlistNode listenNode;
98 FILLP_INT listenBacklog;
99 SYS_ARCH_SEM acceptSem;
100 FillpQueue *acceptBox;
101
102 void *recvPktBuf;
103 struct SpungeInstance *inst;
104 void *traceHandle; /* Handle provided by FillpTrace callback */
105
106 struct EventPoll *eventEpoll;
107 SysArchAtomic rcvEvent;
108 SysArchAtomic sendEvent;
109 SysArchAtomic sendEventCount;
110 SysArchAtomic epollWaiting;
111 FILLP_UINT32 errEvent;
112
113 struct Hlist epTaskList;
114 SYS_ARCH_SEM epollTaskListLock;
115
116 /* It means, that A ft-socket can be registered up to 10 epoll instances, not
117 more than that. This value is compile config controlled, App can
118 increase the number if expects more epoll instances for its user application
119 */
120 FILLP_INT associatedEpollInstanceArr[FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED];
121 FILLP_UINT32 associatedEpollInstanceIdx;
122
123 FILLP_UINT32 offset;
124 FILLP_UINT16 dataOptionFlag;
125 FILLP_UINT16 dataOptionSize;
126 FILLP_LLONG jitter;
127 FILLP_LLONG transmit;
128
129 FILLP_UINT16 sockAddrType;
130 FILLP_INT socketType; // get from SockSocket
131 FILLP_INT socketProtocol; // get from SockSocket
132 FILLP_UINT16 flags;
133
134 FILLP_BOOL isListenSock;
135
136 FILLP_UINT8 traceFlag; /* Flag for enable indication User/Network */
137 FILLP_INT freeTimeCount;
138 FILLP_BOOL isSockBind;
139 SYS_ARCH_SEM connBlockSem; /* Used when do connect */
140 SYS_ARCH_RW_SEM sockConnSem; /* Used to protect socket resource not freed */
141 SYS_ARCH_SEM sockCloseProtect; /* To make sure that only one close message posted to fillp thread */
142 FILLP_INT err;
143 struct GlobalAppResource resConf; /* Total size is 15 * sizeof uint32 */
144 FILLP_BOOL lingering;
145 struct linger fillpLinger;
146 FILLP_INT directlySend; /* directly send packet in the app thread instead of in the main thread */
147 };
148
149 #define FILLP_SOCK_SET_ERR(sk, e) ((sk)->err = (e))
150
SockEntryListenSocket(struct HlistNode * node)151 static __inline struct FtSocket *SockEntryListenSocket(struct HlistNode *node)
152 {
153 return (struct FtSocket *)((char *)(node) - (uintptr_t)(&(((struct FtSocket *)0)->listenNode)));
154 }
155
156 #define SOCK_GET_SENDPKTPOOL(_sock) ((_sock)->netconn->pcb->fpcb.send.itemPool)
157 #define SOCK_GET_SENDBOX(_sock) ((_sock)->netconn->pcb->fpcb.send.unsendBox)
158 #define SOCK_GET_RECVBOX(_sock) ((_sock)->netconn->pcb->fpcb.recv.recvBox)
159 #define SOCK_GET_PKTSIZE(_sock) ((_sock)->netconn->pcb->fpcb.pktSize)
160
161 #define SOCK_CONN_TRY_RDLOCK(_sock) SYS_ARCH_RWSEM_TRYRDWAIT(&(_sock)->sockConnSem)
162 #define SOCK_CONN_UNLOCK_RD(_sock) SYS_ARCH_RWSEM_RDPOST(&(_sock)->sockConnSem)
163
164 #define SOCK_CONN_TRY_LOCK_CLOSE(_sock) SYS_ARCH_SEM_TRYWAIT(&(_sock)->sockCloseProtect)
165 #define SOCK_CONN_UNLOCK_CLOSE(_sock) SYS_ARCH_SEM_POST(&(_sock)->sockCloseProtect)
166
167 #define SOCK_GET_SENDSEM(_sock) ((_sock)->netconn->pcb->fpcb.send.sendSem)
168 #define SOCK_GET_RECVSEM(_sock) ((_sock)->netconn->pcb->fpcb.recv.recvSem)
169
170 #define SOCK_WAIT_SENDSEM(_sock) SYS_ARCH_SEM_WAIT(&SOCK_GET_SENDSEM(_sock))
171 #define SOCK_POST_SENDSEM(_sock) SYS_ARCH_SEM_POST(&SOCK_GET_SENDSEM(_sock))
172 #define SOCK_TRYWAIT_SENDSEM(_sock) SYS_ARCH_SEM_TRYWAIT(&SOCK_GET_SENDSEM(_sock))
173
174 #define SOCK_WAIT_RECVSEM(_sock) SYS_ARCH_SEM_WAIT(&SOCK_GET_RECVSEM(_sock))
175 #define SOCK_POST_RECVSEM(_sock) SYS_ARCH_SEM_POST(&SOCK_GET_RECVSEM(_sock))
176 #define SOCK_TRYWAIT_RECVSEM(_sock) SYS_ARCH_SEM_TRYWAIT(&SOCK_GET_RECVSEM(_sock))
177
178 #ifdef FILLP_LINUX
179 #if defined(FILLP_LW_LITEOS)
180 #define SOCK_SEND_CPU_PAUSE() FILLP_SLEEP_MS(10)
181 #else
182 #define SOCK_SEND_CPU_PAUSE() (void)FILLP_USLEEP(FILLP_CPU_PAUSE_TIME)
183 #endif
184 #else
185 #define SOCK_SEND_CPU_PAUSE() FILLP_SLEEP_MS(1)
186 #endif
187
188 #if defined(FILLP_LW_LITEOS)
189 #define SOCK_RECV_CPU_PAUSE() FILLP_SLEEP_MS(10)
190 #else
191 #define SOCK_RECV_CPU_PAUSE() FILLP_SLEEP_MS(1)
192 #endif
193
194 #ifdef FILLP_LINUX
195 #define EPOLL_CPU_PAUSE() (void)FILLP_USLEEP(FILLP_CPU_PAUSE_TIME)
196 #else
197 #define EPOLL_CPU_PAUSE() FILLP_SLEEP_MS(1)
198 #endif
199
200 struct FtSocketTable {
201 FillpQueue *freeQueqe;
202 struct FtSocket **sockPool;
203 FILLP_INT size;
204 SysArchAtomic used;
205 };
206
207 #ifdef FILLP_LINUX
208 #define SET_ERRNO(_errno) (errno = (_errno))
209 #elif defined(FILLP_WIN32)
210 #define SET_ERRNO(_errno) WSASetLastError(_errno)
211 #endif
212
213 #ifdef FILLP_LINUX
214 #define FT_OS_GET_ERRNO errno
215 #elif defined(FILLP_WIN32)
216 #define FT_OS_GET_ERRNO WSAGetLastError()
217 #endif
218
219 /* Should this netconn avoid blocking? */
220 #define SOCK_FLAG_NON_BLOCKING 0x0001
221
222 /* Get the blocking status of netconn calls (@todo: write/send is missing) */
223 #define SOCK_IS_NONBLOCKING(sock) (((sock)->flags & SOCK_FLAG_NON_BLOCKING) != 0)
224 #define SOCK_IS_BLOCKING(sock) (((sock)->flags & SOCK_FLAG_NON_BLOCKING) == 0)
225
226 /* Set the blocking status of FtSocket
227
228 The flag (which contains the socket options is in FtSocket and NOT in netconn CB)
229 is in FtSocket structure, this is because: Application can set the socket to
230 nonblock just after calling FtSocket (before ft_connet/FtAccept), but the
231 netconn CB will be available only during FtConnect/FtAccept.
232 */
233 void SockSetNonblocking(struct FtSocket *sock, FILLP_INT val);
234
235 struct NackDelayCfg {
236 FILLP_INT sockIndex;
237 FILLP_UINT32 nackCfgVal;
238 FILLP_LLONG nackDelayTimeout;
239 };
240
241 FILLP_INT SysArchSetSockRcvbuf(FILLP_INT sock, FILLP_UINT size);
242 FILLP_INT SysArchSetSockSndbuf(FILLP_INT sock, FILLP_UINT size);
243 FILLP_INT SysArchSetSockBlocking(FILLP_INT sock, FILLP_BOOL blocking);
244 FILLP_INT SysSetThreadName(FILLP_CHAR *name, FILLP_UINT16 nameLen);
245
246 #ifdef __cplusplus
247 }
248 #endif
249
250 #endif /* FILLP_SOCKETS_H */