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