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 #include "res.h"
17 #include "spunge.h"
18 #include "spunge_core.h"
19 #include "socket_common.h"
20 #include "fillp_flow_control.h"
21 #include "net.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
NetconnFreeOsSocket(struct SockOsSocket * osSock,struct SpungeInstance * curInst)27 static void NetconnFreeOsSocket(struct SockOsSocket *osSock, struct SpungeInstance *curInst)
28 {
29     if ((osSock == FILLP_NULL_PTR) || (curInst == FILLP_NULL_PTR)) {
30         /* No need to prin the error log in this case, because the param 'ftSock->osSocket'
31            can be set to NULL only in this function below, so printing log here is
32            not useful
33         */
34         return;
35     }
36 
37     osSock->reference--;
38     if (osSock->reference <= 0) {
39         if (OS_SOCK_OPS_FUNC_VALID(osSock, destroySysIoSocket)) {
40             (void)osSock->ioSock->ops->destroySysIoSocket(osSock->ioSock);
41         }
42         HlistDelete(&curInst->osSockist, &osSock->osListNode);
43         SpungeFree(osSock, SPUNGE_ALLOC_TYPE_CALLOC);
44     }
45 }
46 
47 
NetconnSetSock(struct FtSocket * sock,struct FtNetconn * conn)48 void NetconnSetSock(struct FtSocket *sock, struct FtNetconn *conn)
49 {
50     sock->netconn = conn;
51     conn->sock = (void *)sock;
52 }
53 
NetconnSetSendCacheSize(struct FtNetconn * conn,FILLP_UINT32 cacheSize)54 void NetconnSetSendCacheSize(struct FtNetconn *conn, FILLP_UINT32 cacheSize)
55 {
56     SpungePcbSetSendCacheSize(conn->pcb, cacheSize);
57 }
NetconnSetRecvCacheSize(struct FtNetconn * conn,FILLP_UINT32 cacheSize)58 void NetconnSetRecvCacheSize(struct FtNetconn *conn, FILLP_UINT32 cacheSize)
59 {
60     SpungePcbSetRecvCacheSize(conn->pcb, cacheSize);
61 }
NetconnSetPktSize(struct FtNetconn * conn,FILLP_UINT32 pktSize)62 void NetconnSetPktSize(struct FtNetconn *conn, FILLP_UINT32 pktSize)
63 {
64     SpungePcbSetPktSize(conn->pcb, pktSize);
65 }
66 
NetconnSetOpersiteRate(struct FtNetconn * conn,FILLP_UINT32 rate)67 void NetconnSetOpersiteRate(struct FtNetconn *conn, FILLP_UINT32 rate)
68 {
69     SpungePcbSetOppositeRate(conn->pcb, rate);
70 }
71 
NetconnSetSlowStart(struct FtNetconn * conn,FILLP_BOOL slowStart)72 void NetconnSetSlowStart(struct FtNetconn *conn, FILLP_BOOL slowStart)
73 {
74     SpungePcbSetSlowStart(conn->pcb, slowStart);
75 }
76 
NetconnSetPackInterval(struct FtNetconn * conn,FILLP_UINT32 interval)77 void NetconnSetPackInterval(struct FtNetconn *conn, FILLP_UINT32 interval)
78 {
79     SpungePcbSetPackInterval(conn->pcb, interval);
80 }
81 
NetconnSetLocalPort(struct FtNetconn * conn,FILLP_INT port)82 void NetconnSetLocalPort(struct FtNetconn *conn, FILLP_INT port)
83 {
84     SpungePcbSetLocalPort(conn->pcb, port);
85 }
86 
NetconnSetAddrType(struct FtNetconn * conn,FILLP_UINT16 addrType)87 void NetconnSetAddrType(struct FtNetconn *conn, FILLP_UINT16 addrType)
88 {
89     SpungePcbSetAddrType(conn->pcb, addrType);
90 }
91 
NetconnSetDirectlySend(struct FtNetconn * conn,FILLP_INT directlySend)92 void NetconnSetDirectlySend(struct FtNetconn *conn, FILLP_INT directlySend)
93 {
94     SpungePcbSetDirectlySend(conn->pcb, directlySend);
95 }
96 
NetconnSetConnectTimeout(struct FtNetconn * conn,FILLP_LLONG timeoutUs)97 void NetconnSetConnectTimeout(struct FtNetconn *conn, FILLP_LLONG timeoutUs)
98 {
99     conn->connTimeout = SYS_ARCH_GET_CUR_TIME_LONGLONG() + timeoutUs;
100 }
101 
NetconnIsConnectTimeout(struct FtNetconn * conn)102 FILLP_BOOL NetconnIsConnectTimeout(struct FtNetconn *conn)
103 {
104     return conn->connTimeout <= SYS_ARCH_GET_CUR_TIME_LONGLONG();
105 }
106 
FillpNetconnAlloc(FILLP_UINT16 domain,struct SpungeInstance * inst)107 struct FtNetconn *FillpNetconnAlloc(FILLP_UINT16 domain, struct SpungeInstance *inst)
108 {
109     struct FtNetconn *conn = FILLP_NULL_PTR;
110     FILLP_INT ret;
111 
112     FILLP_UNUSED_PARA(domain);
113 
114     ret = DympAlloc(g_spunge->netPool, (void **)&conn, FILLP_FALSE);
115     if (conn == FILLP_NULL_PTR) {
116         FILLP_LOGERR("Failed to allocate the netconn connection, Ret=%d", ret);
117         return FILLP_NULL_PTR;
118     }
119 
120     (void)memset_s(conn, sizeof(struct FtNetconn), 0, sizeof(struct FtNetconn));
121 
122     FillpNetconnSetState(conn, CONN_STATE_IDLE);
123 
124     conn->pcb = SpungePcbNew(conn, inst);
125     if (conn->pcb == FILLP_NULL_PTR) {
126         FILLP_LOGERR("alloc spunge_pcb fail");
127         DympFree(conn);
128         return FILLP_NULL_PTR;
129     }
130 
131     conn->pcb->conn = conn;
132 
133     conn->clientFourHandshakeState = FILLP_CLIENT_FOUR_HANDSHAKE_STATE_INITIAL;
134 
135     conn->closeSet = 0;   /* Application calls close() function */
136     conn->shutdownRdSet = 0; /* Application called shutdown(sock, RD) */
137     conn->shutdownWrSet = 0;   /* Application called shutdown(sock, WR) */
138     conn->peerRdSet = 0;       /* Peer notify that it won't read anything */
139     conn->peerWrSet = 0;       /* Peer notify that it won't send anything */
140     conn->sendBufRunOut = 0;    /* Send buffer has run out */
141     conn->flagsReverse = 0;
142     conn->calcRttDuringConnect = 0;
143 #ifdef FILLP_LINUX
144     conn->iovCount = 0;
145 #endif
146     return conn;
147 }
148 
FillpNetconnDestroy(struct FtNetconn * conn)149 void FillpNetconnDestroy(struct FtNetconn *conn)
150 {
151     int i;
152     if (conn == FILLP_NULL_PTR) {
153         FILLP_LOGERR("FillpNetconnDestroy: Invalid paramaters passed");
154         return;
155     }
156 
157     FillpDisableConnRetryCheckTimer(&conn->pcb->fpcb);
158 
159     conn->clientFourHandshakeState = FILLP_CLIENT_FOUR_HANDSHAKE_STATE_INITIAL;
160 
161     SpungePcbRemove(conn->pcb);
162     conn->pcb = FILLP_NULL_PTR;
163 
164     for (i = 0; i < MAX_SPUNGEINSTANCE_NUM; i++) {
165         if (conn->osSocket[i] != FILLP_NULL_PTR) {
166             NetconnFreeOsSocket(conn->osSocket[i], SPUNGE_GET_CUR_INSTANCE());
167             conn->osSocket[i] = FILLP_NULL_PTR;
168         }
169     }
170 
171     DympFree(conn);
172 }
173 
FillpErrIsFatal(FILLP_INT err)174 static FILLP_BOOL FillpErrIsFatal(FILLP_INT err)
175 {
176     FILLP_BOOL isFatal;
177     switch (err) {
178         case ERR_OK:
179         case FILLP_ERR_ISCONN:
180         case FILLP_ERR_EALREADY:
181         case ERR_NOBUFS:
182         case ERR_EINPROGRESS:
183         case ERR_CONN_TIMEOUT:
184         case ERR_NORES:
185             isFatal = FILLP_FALSE;
186             break;
187         default:
188             isFatal = FILLP_TRUE;
189             break;
190     }
191 
192     return isFatal;
193 }
194 
FillpErrToErrno(FILLP_INT err)195 FILLP_INT FillpErrToErrno(FILLP_INT err)
196 {
197     switch (err) {
198         case ERR_OK:
199             return FILLP_OK;
200         case FILLP_ERR_ISCONN:
201             return FILLP_EISCONN;
202         case FILLP_ERR_EALREADY:
203             return FILLP_EALREADY;
204         case ERR_NOBUFS:
205             return FILLP_ENOBUFS;
206         case ERR_EINPROGRESS:
207             return FILLP_EINPROGRESS;
208         case ERR_PARAM:
209             return FILLP_EINVAL;
210         case ERR_CONN_TIMEOUT:
211             return FILLP_ETIMEDOUT;
212         case ERR_WRONGSTATE:
213             return FILLP_EINVAL;
214         case ERR_NO_SOCK:
215             return FILLP_ENOTSOCK;
216         case ERR_FAILURE:
217             return FILLP_EFAULT;
218         case ERR_NORES:
219             return FILLP_ENOMEM;
220         case ERR_NO_SYS_SOCK:
221             return FILLP_EFAULT;
222         case ERR_NO_REBIND:
223             return FILLP_EINVAL;
224         case ERR_SOCK_BIND:
225             return FILLP_EINVAL;
226         case ERR_REMOTE_REJECT_OR_CLOSE:
227             return FILLP_ECONNRESET;
228         case ERR_CONNREFUSED:
229             return FILLP_ECONNREFUSED;
230         default:
231             return FILLP_EFAULT;
232     }
233 }
234 
FillpNetconnSetSafeErr(struct FtNetconn * conn,FILLP_INT err)235 void FillpNetconnSetSafeErr(struct FtNetconn *conn, FILLP_INT err)
236 {
237     if (!FillpErrIsFatal(conn->lastErr)) {
238         conn->lastErr = err;
239     }
240 }
241 
FillpNetconnSetState(struct FtNetconn * conn,FILLP_UINT8 state)242 void FillpNetconnSetState(struct FtNetconn *conn, FILLP_UINT8 state)
243 {
244     conn->state = state;
245     FILLP_LOGINF("Set conn state:%u", state);
246 
247     if (state == CONN_STATE_CONNECTED) {
248         FillpEnablePackTimer(&conn->pcb->fpcb);
249         FillpEnableFcTimer(&conn->pcb->fpcb);
250 
251         FillpEnableKeepAliveTimer(&conn->pcb->fpcb);
252         conn->pcb->fpcb.statistics.keepAlive.lastRecvTime = conn->pcb->fpcb.pcbInst->curTime;
253 
254         if (g_resource.common.outOfOrderCacheEnable &&
255             (g_appResource.common.enableNackDelay == FILLP_FALSE)) {
256             conn->pcb->fpcb.dataBurstTimerNode.interval =
257                 (FILLP_UINT32)(g_resource.common.recvCachePktNumBufferTimeout * FILLP_ONE_SECOND);
258             FillpEnableDataBurstTimer(&conn->pcb->fpcb);
259         }
260 
261         SpungeTokenBucketAddFpcb(&conn->pcb->fpcb);
262     }
263 
264     if (state == CONN_STATE_CLOSED) {
265         if (conn->pcb != FILLP_NULL_PTR) {
266             SpungeTokenBucketDelFpcb(&conn->pcb->fpcb);
267         }
268     }
269 }
270 
271 #ifdef __cplusplus
272 }
273 #endif
274 
275