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 "spunge_stack.h"
17 #include "spunge_app.h"
18 #include "res.h"
19 #include "socket_common.h"
20 #include "fillp_dfx.h"
21 #include "spunge_message.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif /* __cplusplus */
26 
SpungePostMsg(struct SpungeInstance * inst,void * value,FILLP_INT type,FILLP_BOOL block)27 FillpErrorType SpungePostMsg(struct SpungeInstance *inst, void *value, FILLP_INT type, FILLP_BOOL block)
28 {
29     struct SpungeMsg *msg = FILLP_NULL_PTR;
30     FillpErrorType err;
31 
32     if ((inst == FILLP_NULL_PTR) || (value == FILLP_NULL_PTR) || (inst->msgPool == FILLP_NULL_PTR)) {
33         FILLP_LOGERR("invalid input params");
34         return ERR_PARAM;
35     }
36 
37     err = DympAlloc(inst->msgPool, (void **)&msg, FILLP_FALSE);
38     if ((err != ERR_OK) || (msg == FILLP_NULL_PTR)) {
39         FILLP_LOGERR("failed to allocate the msgpool\n");
40         return err;
41     }
42 
43     (void)SYS_ARCH_ATOMIC_INC(&inst->msgUsingCount, 1);
44     msg->msgType = type;
45     msg->value = value;
46     msg->block = block;
47 
48     err = FillpQueuePush(inst->msgBox, (void *)&msg, FILLP_FALSE, 1);
49     if (err != ERR_OK) {
50         FILLP_LOGERR("Failed to push the message in msgBox queue , MessageType = %d", type);
51         DympFree(msg);
52         (void)SYS_ARCH_ATOMIC_DEC(&inst->msgUsingCount, 1);
53         return err;
54     }
55 
56     if (msg->block) {
57         if (SYS_ARCH_SEM_WAIT(&msg->syncSem)) {
58             FILLP_LOGWAR("sem wait failed");
59             (void)SYS_ARCH_ATOMIC_DEC(&inst->msgUsingCount, 1);
60             DympFree(msg);
61             return ERR_COMM;
62         }
63         DympFree(msg);
64     }
65     (void)SYS_ARCH_ATOMIC_DEC(&inst->msgUsingCount, 1);
66 
67     return ERR_OK;
68 }
69 
SpungeHandleMsgAllocSock(void * value,struct SpungeInstance * inst)70 static void SpungeHandleMsgAllocSock(void *value, struct SpungeInstance *inst)
71 {
72     if (value == FILLP_NULL_PTR) {
73         FILLP_LOGERR("Invalid socket");
74         return;
75     }
76 
77     struct SpungeSocketMsg *msg = (struct SpungeSocketMsg *)value;
78     struct FtSocket *sock = (struct FtSocket *)msg->sock;
79     FILLP_LOGINF("fillp_sock_id:%d", sock->index);
80     struct FtNetconn *conn = FillpNetconnAlloc(sock->sockAddrType, inst);
81     if (conn == FILLP_NULL_PTR) {
82         FILLP_LOGERR("Error to alloc netconn");
83         sock->allocState = SOCK_ALLOC_STATE_ERR;
84         SET_ERRNO(FILLP_ENOMEM);
85         sock->coreErrType[MSG_TYPE_ALLOC_SOCK] = FILLP_EMFILE;
86         return;
87     }
88 
89     NetconnSetRecvCacheSize(conn, sock->resConf.common.recvCache);
90     NetconnSetSendCacheSize(conn, sock->resConf.common.sendCache);
91     FillpInitNewconnBySock(conn, sock);
92 
93     FILLP_LOGINF("conn:recvSize:%u,sendSize:%u,pktSize:%u,opersite:%u,slowStart:%u,addrType:%u",
94         sock->resConf.common.sendCache, sock->resConf.common.recvCache, sock->resConf.flowControl.pktSize,
95         sock->resConf.flowControl.oppositeSetRate, sock->resConf.flowControl.slowStart, sock->sockAddrType);
96 
97     NetconnSetSock(sock, conn);
98 
99     struct SockOsSocket *osSock = SpungeAllocSystemSocket(msg->domain, msg->type, msg->protocol);
100     if (osSock == FILLP_NULL_PTR) {
101         FILLP_LOGERR("sock alloc sys sock failed. socketId=%d", sock->index);
102         sock->allocState = SOCK_ALLOC_STATE_ERR;
103         FILLP_INT errorNum = FtGetErrno();
104         if (errorNum == ERR_OK) {
105             SET_ERRNO(FILLP_EMFILE);
106             errorNum = FILLP_EMFILE;
107         }
108         sock->coreErrType[MSG_TYPE_ALLOC_SOCK] = errorNum;
109         FillpNetconnDestroy(conn);
110         return;
111     }
112 
113     SockSetOsSocket(sock, osSock);
114     sock->coreErrType[MSG_TYPE_ALLOC_SOCK] = ERR_OK;
115     sock->netconn->lastErr = ERR_OK;
116 }
117 
SpungeHandleMsgFreeSockEagain(void * value,struct SpungeInstance * inst)118 static void SpungeHandleMsgFreeSockEagain(void *value, struct SpungeInstance *inst)
119 {
120     struct FtSocket *sock = FILLP_NULL_PTR;
121     FILLP_UNUSED_PARA(inst);
122 
123     if (value == FILLP_NULL_PTR) {
124         FILLP_LOGERR("SpungeHandleMsgFreeSockEagain failed : invalid socket \r\n");
125         return;
126     }
127 
128     sock = (struct FtSocket *)value;
129     FILLP_LOGDBG("MSG_TYPE_FREE_SOCK_EAGIN, sock = %d, allocState = %d\n", sock->index, sock->allocState);
130     if ((sock->allocState == SOCK_ALLOC_STATE_EPOLL) || (sock->allocState == SOCK_ALLOC_STATE_EPOLL_TO_CLOSE)) {
131         SpungEpollClose(sock);
132         return;
133     }
134 
135     SpungeFreeSock(sock);
136 }
137 
SpungeListenMsgCheckState(void * value,struct SpungeInstance * inst,struct FtSocket ** pSock,struct SockOsSocket ** pOsSock)138 static FILLP_INT SpungeListenMsgCheckState(void *value, struct SpungeInstance *inst,
139     struct FtSocket **pSock, struct SockOsSocket **pOsSock)
140 {
141     struct FtSocket *sock = FILLP_NULL_PTR;
142     struct SockOsSocket *osSock = FILLP_NULL_PTR;
143     struct FtNetconn *netconn = FILLP_NULL_PTR;
144     int netState;
145 
146     if ((value == FILLP_NULL_PTR) || (inst == FILLP_NULL_PTR)) {
147         FILLP_LOGERR("invalid param");
148         return -1;
149     }
150 
151     sock = (struct FtSocket *)value;
152     FILLP_LOGINF("MSG_TYPE_DO_LISTEN fillp_sock_id:%d,inst:%d", sock->index, inst->instIndex);
153 
154     netconn = sock->netconn;
155     netState = NETCONN_GET_STATE(netconn);
156     if (netState != CONN_STATE_IDLE) {
157         FILLP_LOGERR("netconn state error state:%d", netState);
158         SET_ERRNO(FILLP_ENOTCONN);
159         sock->coreErrType[MSG_TYPE_DO_LISTEN] = ERR_WRONGSTATE;
160         return -1;
161     }
162 
163     FillpNetconnSetState(netconn, CONN_STATE_LISTENING);
164 
165     /* For server socket, should listen on every instance */
166     osSock = NETCONN_GET_OSSOCK(sock->netconn, inst->instIndex);
167     if (osSock == FILLP_NULL_PTR) {
168         FILLP_LOGERR("Can't find osSocket, socketId=%d", sock->index);
169         sock->allocState = SOCK_ALLOC_STATE_ERR;
170         SET_ERRNO(FILLP_ENOMEM);
171         sock->coreErrType[MSG_TYPE_DO_LISTEN] = ERR_NO_SOCK;
172         return -1;
173     }
174 
175     sock->coreErrType[MSG_TYPE_DO_LISTEN] = ERR_OK;
176     FILLP_SOCK_SET_ERR(sock, ERR_OK);
177 
178     *pSock = sock;
179     *pOsSock = osSock;
180 
181     return FILLP_OK;
182 }
183 
SpungeHandleMsgListen(void * value,struct SpungeInstance * inst)184 static void SpungeHandleMsgListen(void *value, struct SpungeInstance *inst)
185 {
186     struct FtSocket *sock = FILLP_NULL_PTR;
187     struct SockOsSocket *osSock = FILLP_NULL_PTR;
188     FILLP_INT err;
189 
190     if (SpungeListenMsgCheckState(value, inst, &sock, &osSock) != FILLP_OK) {
191         return;
192     }
193 
194     err = SYS_ARCH_SEM_INIT(&sock->acceptSem, 0);
195     if (err != ERR_OK) {
196         FILLP_LOGERR("Init accept semaphore error");
197         SET_ERRNO(FILLP_EFAULT);
198         sock->coreErrType[MSG_TYPE_DO_LISTEN] = ERR_FAILURE;
199         return;
200     }
201 
202     sock->acceptBox =
203         FillpQueueCreate("acceptBox", (FILLP_SIZE_T)(unsigned int)sock->listenBacklog, SPUNGE_ALLOC_TYPE_MALLOC);
204 
205     if (sock->acceptBox == FILLP_NULL_PTR) {
206         FILLP_LOGERR("accept box Queue create failed sock=%d", sock->index);
207 
208         SET_ERRNO(FILLP_ENOMEM);
209         sock->coreErrType[MSG_TYPE_DO_LISTEN] = ERR_NOBUFS;
210 
211         (void)SYS_ARCH_SEM_DESTROY(&sock->acceptSem);
212         return;
213     }
214 
215     FillpQueueSetConsSafe(sock->acceptBox, FILLP_TRUE);
216     FillpQueueSetProdSafe(sock->acceptBox, FILLP_TRUE);
217 
218     // Listen socket should not report error and out event at  the first time it added to epoll
219     sock->errEvent = 0;
220     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEvent, 0);
221     if (!OS_SOCK_OPS_FUNC_VALID(osSock, listen) || osSock->ioSock->ops->listen(sock) != ERR_OK) {
222         sock->coreErrType[MSG_TYPE_DO_LISTEN] = ERR_FAILURE;
223         FillpQueueDestroy(sock->acceptBox);
224         sock->acceptBox = FILLP_NULL;
225         return;
226     }
227     sock->isListenSock = FILLP_TRUE;
228 }
229 
SpungeConnMsgCheckSockState(struct FtSocket * sock,FILLP_INT connState)230 static FILLP_INT SpungeConnMsgCheckSockState(struct FtSocket *sock, FILLP_INT connState)
231 {
232     if (connState == CONN_STATE_CONNECTED) {
233         SET_ERRNO(FILLP_EISCONN);
234         sock->coreErrType[MSG_TYPE_DO_CONNECT] = FILLP_ERR_ISCONN;
235         FILLP_LOGERR("Netconn is already connected, fillp_sock_id:%d,state:%d", sock->index, connState);
236         return -1;
237     }
238 
239     if (connState != CONN_STATE_IDLE) {
240         if (connState == CONN_STATE_CONNECTING) {
241             SET_ERRNO(FILLP_EALREADY);
242             sock->coreErrType[MSG_TYPE_DO_CONNECT] = FILLP_ERR_EALREADY;
243         } else {
244             SET_ERRNO(FILLP_EBADF);
245             sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_PARAM;
246         }
247 
248         FILLP_LOGERR("Netconn state is not idle, fillp_sock_id:%d,state:%d", sock->index, connState);
249         return -1;
250     }
251     return ERR_OK;
252 }
253 
SpungeConnMsgGetSock(void * value,struct FtSocket ** pSock,struct SockOsSocket ** pOsSock)254 static FILLP_INT SpungeConnMsgGetSock(void *value, struct FtSocket **pSock, struct SockOsSocket **pOsSock)
255 {
256     FillpErrorType err;
257     int connState;
258     struct SpungeConnectMsg *connMsg = (struct SpungeConnectMsg *)value;
259     struct FtSocket *sock = (struct FtSocket *)connMsg->sock;
260     struct SockOsSocket *osSock = FILLP_NULL_PTR;
261 
262     *pSock = sock;
263     if (sock->netconn == FILLP_NULL_PTR) {
264         FILLP_LOGERR("sock->netconn is NULL, fillp_sock_id:%d", sock->index);
265         SET_ERRNO(FILLP_EPIPE);
266         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_PARAM;
267         return -1;
268     }
269 
270     err = memcpy_s(&sock->netconn->pcb->remoteAddr, sizeof(sock->netconn->pcb->remoteAddr), connMsg->addr,
271         connMsg->addrLen);
272     if (err != EOK) {
273         FILLP_LOGERR("SpungeHandleMsgConnect memcpy_s failed: %d fillp_sock_id:%d", err, sock->index);
274         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_PARAM;
275         return -1;
276     }
277     sock->netconn->pcb->addrLen = (FILLP_UINT16)connMsg->addrLen;
278 
279     osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
280     if (osSock == FILLP_NULL_PTR) {
281         FILLP_LOGERR("Can't get osSocket, fillp_sock_id:%d", sock->index);
282         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_PARAM;
283         return -1;
284     }
285 
286     connState = NETCONN_GET_STATE(sock->netconn);
287     if (SpungeConnMsgCheckSockState(sock, connState) != ERR_OK) {
288         return -1;
289     }
290 
291     *pOsSock = osSock;
292 
293     return FILLP_OK;
294 }
295 
SpungeStartConnRetryTimer(struct FillpPcb * fpcb,FILLP_CONST struct FtSocket * sock)296 static void SpungeStartConnRetryTimer(struct FillpPcb *fpcb, FILLP_CONST struct FtSocket *sock)
297 {
298     FILLP_TIMING_WHEEL_INIT_NODE(&fpcb->connRetryTimeoutTimerNode);
299     fpcb->connRetryTimeoutTimerNode.cbNode.cb = SpungeSendConnectMsg;
300     fpcb->connRetryTimeoutTimerNode.cbNode.arg = (void *)sock->netconn;
301     fpcb->connRetryTimeoutTimerNode.interval = (FILLP_UINT32)FILLP_UTILS_MS2US(sock->resConf.common.connRetryTimeout);
302 
303     FillpEnableConnRetryCheckTimer(fpcb);
304 }
305 
SpungeHandleMsgConnect(void * value,struct SpungeInstance * inst)306 static void SpungeHandleMsgConnect(void *value, struct SpungeInstance *inst)
307 {
308     struct FtSocket *sock = FILLP_NULL_PTR;
309     struct SockOsSocket *osSock = FILLP_NULL_PTR;
310 
311     if (value == FILLP_NULL_PTR) {
312         FILLP_LOGERR("Failed : invalid value");
313         return;
314     }
315 
316     FILLP_UNUSED_PARA(inst);
317 
318     if (SpungeConnMsgGetSock(value, &sock, &osSock) != FILLP_OK) {
319         goto FAIL;
320     }
321 
322     if (!OS_SOCK_OPS_FUNC_VALID(osSock, connect) ||
323         osSock->ioSock->ops->connect(osSock->ioSock, sock->netconn->pcb) != ERR_OK) {
324         FILLP_LOGERR("sysio connect fail");
325         SET_ERRNO(FILLP_EINVAL);
326         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_PARAM;
327         goto FAIL;
328     }
329 
330     NetconnSetConnectTimeout(sock->netconn, FILLP_UTILS_MS2US((FILLP_LLONG)sock->resConf.common.connectTimeout));
331     NetconnSetDirectlySend(sock->netconn, sock->directlySend);
332 
333     SpungeStartConnRetryTimer(&sock->netconn->pcb->fpcb, sock);
334 
335     FillpNetconnSetState(sock->netconn, CONN_STATE_CONNECTING);
336 
337     if (!OS_SOCK_OPS_FUNC_VALID(osSock, sendPacket) ||
338         (osSock->ioSock->ops->sendPacket(FILLP_PKT_TYPE_CONN_REQ, (void *)osSock->ioSock,
339         (void *)sock->netconn->pcb, FILLP_NULL_PTR) == -1)) {
340         FillpDisableConnRetryCheckTimer(&sock->netconn->pcb->fpcb);
341         SET_ERRNO(FILLP_ECONNREFUSED);
342         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_CONNREFUSED;
343         goto FAIL;
344     }
345 
346     if (!SOCK_IS_NONBLOCKING(sock)) {
347         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_OK;
348     } else {
349         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_NONBLOCK_UNDERCONNECT;
350     }
351 
352     if (SOCK_IS_NONBLOCKING(sock)) {
353         (void)SYS_ARCH_SEM_POST(&sock->connBlockSem);
354     }
355     /* IMP: linux do not give HUP while connecting, so do not add any error event.
356         Also in linux till connect success and connect fail (during connection establishment) there is
357         no event reproted for the socket
358     */
359     sock->errEvent = 0;
360     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEvent, 0);
361 
362     return;
363 
364 FAIL:
365     (void)SYS_ARCH_SEM_POST(&sock->connBlockSem);
366 }
367 
SpungeBindMsgCheckState(struct FtSocket * sock,struct SockOsSocket ** pOsSock,struct FtNetconn ** pConn,struct SpungePcb ** pPcb)368 static FILLP_INT SpungeBindMsgCheckState(struct FtSocket *sock, struct SockOsSocket **pOsSock,
369     struct FtNetconn **pConn, struct SpungePcb **pPcb)
370 {
371     struct SockOsSocket *osSock = FILLP_NULL_PTR;
372     struct FtNetconn *conn = FILLP_NULL_PTR;
373     struct SpungePcb *pcb = FILLP_NULL_PTR;
374     FILLP_INT connState;
375 
376     conn = sock->netconn;
377     if (conn == FILLP_NULL_PTR) {
378         FILLP_LOGERR("conn is NULL fillp_sock_id:%d", sock->index);
379         sock->coreErrType[MSG_TYPE_DO_BIND] = FILLP_ERR_CONN;
380         SET_ERRNO(FILLP_EBADF);
381         return -1;
382     }
383 
384     pcb = conn->pcb;
385     if (pcb == FILLP_NULL_PTR) {
386         sock->coreErrType[MSG_TYPE_DO_BIND] = FILLP_ERR_CONN;
387         FILLP_LOGERR("PCB is null fillp_sock_id:%d", sock->index);
388         SET_ERRNO(FILLP_EBADF);
389         return -1;
390     }
391 
392     connState = NETCONN_GET_STATE(sock->netconn);
393     if (connState != CONN_STATE_IDLE) {
394         sock->coreErrType[MSG_TYPE_DO_BIND] = FILLP_ERR_CONN;
395         FILLP_LOGERR("Connect state is not idle fillp_sock_id:%d", sock->index);
396         SET_ERRNO(FILLP_EBADF);
397         return -1;
398     }
399 
400     osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
401 
402     if (sock->isSockBind) {
403         sock->coreErrType[MSG_TYPE_DO_BIND] = ERR_NO_REBIND;
404         FILLP_LOGERR("Socket already do bind before fillp_sock_id:%d", sock->index);
405         SET_ERRNO(FILLP_EADDRINUSE);
406         return -1;
407     }
408 
409     *pOsSock = osSock;
410     *pConn = conn;
411     *pPcb = pcb;
412 
413     return FILLP_OK;
414 }
415 
SpungeHandleMsgBind(void * value,struct SpungeInstance * inst)416 static void SpungeHandleMsgBind(void *value, struct SpungeInstance *inst)
417 {
418     struct FtSocket *sock = FILLP_NULL_PTR;
419     struct SockOsSocket *osSock = FILLP_NULL_PTR;
420     struct FtNetconn *conn = FILLP_NULL_PTR;
421     struct SpungePcb *pcb = FILLP_NULL_PTR;
422 
423     FillpErrorType err;
424     FILLP_UINT32 addrLen;
425     struct SpungeBindMsg *bindMsg = FILLP_NULL_PTR;
426     struct sockaddr_in *localAddr = FILLP_NULL_PTR;
427     FILLP_INT sysErrno;
428 
429     FILLP_UNUSED_PARA(inst);
430 
431     bindMsg = (struct SpungeBindMsg *)value;
432     sock = (struct FtSocket *)bindMsg->sock;
433     localAddr = bindMsg->addr;
434     addrLen = bindMsg->addrLen;
435 
436     if (SpungeBindMsgCheckState(sock, &osSock, &conn, &pcb) != FILLP_OK) {
437         return;
438     }
439 
440     err = memcpy_s(&pcb->localAddr, sizeof(pcb->localAddr), localAddr, addrLen);
441     if (err != ERR_OK) {
442         FILLP_LOGERR("memcpy_s failed with errcode %d", err);
443         SET_ERRNO(FILLP_EINVAL);
444         sock->coreErrType[MSG_TYPE_DO_BIND] = ERR_NOBUFS;
445         return;
446     }
447     NetconnSetLocalPort(conn, ((struct sockaddr_in *)(&pcb->localAddr))->sin_port);
448 
449     if (!OS_SOCK_OPS_FUNC_VALID(osSock, bind)) {
450         FILLP_LOGERR("os sock ops bind is null");
451         SET_ERRNO(FILLP_EOPNOTSUPP);
452         sock->coreErrType[MSG_TYPE_DO_BIND] = ERR_COMM;
453         return;
454     }
455 
456     err = osSock->ioSock->ops->bind((void *)osSock->ioSock, (void *)conn->pcb, (struct sockaddr *)&pcb->localAddr,
457         (FILLP_UINT16)addrLen);
458     if (err != ERR_OK) {
459         sysErrno = FT_OS_GET_ERRNO;
460         FILLP_LOGERR("system bind fail sock=%d,err=%d, sysErrno=%d", sock->index, err, sysErrno);
461 
462         if (sysErrno == FILLP_EADDRINUSE) {
463             sock->coreErrType[MSG_TYPE_DO_BIND] = ERR_NO_REBIND;
464         } else {
465             sock->coreErrType[MSG_TYPE_DO_BIND] = ERR_SOCK_BIND;
466         }
467         SET_ERRNO(sysErrno);
468         return;
469     }
470 
471     sock->coreErrType[MSG_TYPE_DO_BIND] = ERR_OK;
472     sock->isSockBind = FILLP_TRUE;
473 }
474 
SpungeHandleMsgConnAccepted(void * value,struct SpungeInstance * inst)475 static void SpungeHandleMsgConnAccepted(void *value, struct SpungeInstance *inst)
476 {
477     struct FtSocket *listenSock = FILLP_NULL_PTR;
478     struct FtSocket *sock = FILLP_NULL_PTR;
479     struct SpungeAcceptMsg *acceptMsg = FILLP_NULL_PTR;
480     struct FtNetconn *netconn = FILLP_NULL_PTR;
481 
482     if (value == FILLP_NULL_PTR) {
483         FILLP_LOGERR("Value is NULL");
484         return;
485     }
486 
487     acceptMsg = (struct SpungeAcceptMsg *)value;
488     listenSock = (struct FtSocket *)acceptMsg->listenSock;
489     netconn = (struct FtNetconn *)acceptMsg->netconn;
490 
491     sock = SpungeAllocSock(SOCK_ALLOC_STATE_COMM);
492     if (sock == FILLP_NULL_PTR) {
493         FILLP_LOGERR("Can't alloc socket!!!");
494         SET_ERRNO(FILLP_ENOMEM);
495         listenSock->coreErrType[MSG_TYPE_NETCONN_ACCPETED] = ERR_NORES;
496         return;
497     }
498 
499     sock->dataOptionFlag = 0;
500     (void)SockUpdatePktDataOpt(sock, listenSock->dataOptionFlag, 0);
501     sock->fillpLinger = listenSock->fillpLinger;
502 
503     /* Copy the traace handle from server listen socket to newly accepting socket */
504     sock->traceFlag = listenSock->traceFlag;
505 
506     sock->traceHandle = listenSock->traceHandle;
507     sock->sockAddrType = listenSock->sockAddrType;
508 
509     NetconnSetSock(sock, netconn);
510 
511     listenSock->listenBacklog++;
512 
513     sock->sockAddrType = netconn->pcb->addrType;
514     FillpSendConnConfirmAck(&netconn->pcb->fpcb);
515 
516     sock->resConf.flowControl.pktSize = (FILLP_UINT16)netconn->pcb->fpcb.pktSize;
517     /* Check the connection max rate, it should not be configured to more
518         than the core max rate */
519     sock->resConf.flowControl.maxRate = UTILS_MIN(sock->resConf.flowControl.maxRate, g_resource.flowControl.maxRate);
520     sock->resConf.flowControl.maxRecvRate = UTILS_MIN(sock->resConf.flowControl.maxRecvRate,
521                                                       g_resource.flowControl.maxRecvRate);
522 
523     FILLP_LOGINF("fillp_sock_id:%d "
524         "Accepted connection established time = %lld, local seq num = %u, "
525         "local pkt num = %u, peer seq num = %u peer pkt num = %u, maxRate= %u maxRecvRate= %u",
526         sock->index, SYS_ARCH_GET_CUR_TIME_LONGLONG(), netconn->pcb->fpcb.send.seqNum, netconn->pcb->fpcb.send.pktNum,
527         netconn->pcb->fpcb.recv.seqNum, netconn->pcb->fpcb.recv.pktNum, sock->resConf.flowControl.maxRate,
528         sock->resConf.flowControl.maxRecvRate);
529 
530     FillpNetconnSetState(netconn, CONN_STATE_CONNECTED);
531 
532     sock->coreErrType[MSG_TYPE_NETCONN_ACCPETED] = ERR_OK;
533     FillpNetconnSetSafeErr(netconn, ERR_OK);
534 
535     /* We just reset the err event because if already connected */
536     sock->errEvent = 0;
537     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEvent, 1);
538 
539     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEventCount, (FILLP_INT)netconn->pcb->fpcb.send.curItemCount);
540 
541     /* Implementing Fair Bandwidth sharing among sockets */
542     inst->rateControl.connectionNum++;
543 }
544 
SpungeHandleMsgDoShutdown(void * value,struct SpungeInstance * inst)545 static void SpungeHandleMsgDoShutdown(void *value, struct SpungeInstance *inst)
546 {
547     struct FtSocket *sock = FILLP_NULL_PTR;
548     struct FtNetconn *conn = FILLP_NULL_PTR;
549     FILLP_UINT8 connState;
550     FILLP_INT writeShut = FILLP_FALSE;
551     FILLP_INT readShut = FILLP_FALSE;
552     FILLP_INT howValue;
553     int evt;
554     struct SpungeShutdownMsg *shutdownMsg = FILLP_NULL_PTR;
555 
556     if (value == FILLP_NULL_PTR) {
557         FILLP_LOGERR("NULL value");
558         return;
559     }
560 
561     FILLP_UNUSED_PARA(inst);
562 
563     shutdownMsg = (struct SpungeShutdownMsg *)value;
564     howValue = shutdownMsg->how;
565 
566     sock = (struct FtSocket *)shutdownMsg->sock;
567     conn = sock->netconn;
568     connState = NETCONN_GET_STATE(conn);
569     if (!((connState == CONN_STATE_CONNECTED) || (connState == CONN_STATE_CLOSING))) {
570         goto FINISH;
571     }
572 
573     if (((howValue == SPUNGE_SHUT_RD) || (howValue == SPUNGE_SHUT_RDWR)) && !conn->shutdownRdSet) {
574         readShut = FILLP_TRUE;
575     }
576 
577     if (((howValue == SPUNGE_SHUT_WR) || (howValue == SPUNGE_SHUT_RDWR)) && !conn->shutdownWrSet) {
578         writeShut = FILLP_TRUE;
579     }
580 
581     if ((writeShut == FILLP_FALSE) && (readShut == FILLP_FALSE)) {
582         FILLP_LOGERR("Already shutdown before fillp_sock_id:%d,how:%d", sock->index, shutdownMsg->how);
583         goto FINISH;
584     }
585 
586     FillpDfxSockLinkAndQosNotify(sock, FILLP_DFX_LINK_CLOSE);
587     SpungeShutdownSock(sock, howValue);
588 
589     if (readShut && writeShut) {
590         evt = (FILLP_INT)SPUNGE_EPOLLIN | (FILLP_INT)SPUNGE_EPOLLOUT | (FILLP_INT)SPUNGE_EPOLLRDHUP |
591             (FILLP_INT)SPUNGE_EPOLLHUP;
592     } else if (readShut) {
593         evt = (FILLP_INT)SPUNGE_EPOLLIN | (FILLP_INT)SPUNGE_EPOLLOUT | (FILLP_INT)SPUNGE_EPOLLRDHUP;
594     } else { // just writeShut
595         evt = (FILLP_INT)SPUNGE_EPOLLOUT;
596     }
597     SpungeEpollEventCallback(sock, evt, 1);
598 
599     if (writeShut) { // Need to check the status
600         FillpEnableFinCheckTimer(&conn->pcb->fpcb);
601     }
602 
603 FINISH:
604     sock->coreErrType[MSG_TYPE_DO_SHUTDOWN] = ERR_OK;
605 }
606 
SpungeCloseMsgFreeSrc(struct FtNetconn * conn,struct FtSocket * sock)607 static void SpungeCloseMsgFreeSrc(struct FtNetconn *conn, struct FtSocket *sock)
608 {
609     /* To check if this netconn can release resource or not */
610     switch (NETCONN_GET_STATE(conn)) {
611         case CONN_STATE_IDLE:
612         case CONN_STATE_CLOSED:
613         case CONN_STATE_LISTENING:
614             /* Release resource */
615             SpungeFreeSock(sock);
616             break;
617         case CONN_STATE_CONNECTING:
618             FillpDisableConnRetryCheckTimer(&conn->pcb->fpcb);
619             SET_ERRNO(FILLP_ETIMEDOUT);
620             sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_CONN_TIMEOUT;
621             if (SOCK_IS_NONBLOCKING(sock)) {
622                 FILLP_SOCK_SET_ERR(sock, FILLP_ECONNREFUSED);
623                 FillpNetconnSetSafeErr(conn, ERR_CONNREFUSED);
624             } else {
625                 FillpNetconnSetSafeErr(conn, ERR_CONN_TIMEOUT);
626             }
627             SpungeConnConnectFail(sock);
628             SpungeFreeSock(sock);
629             break;
630         /* once in closing state, this means socket is waiting to close(processing fin)and finCheckTimer is working */
631         case CONN_STATE_CLOSING:
632             break;
633         case CONN_STATE_CONNECTED:
634             FillpEnableFinCheckTimer(&conn->pcb->fpcb);
635             break;
636         default:
637             break;
638     }
639 }
640 
SpungeHandleMsgClose(void * value,struct SpungeInstance * inst)641 static void SpungeHandleMsgClose(void *value, struct SpungeInstance *inst)
642 {
643     struct FtNetconn *conn = FILLP_NULL_PTR;
644     struct FtSocket *sock = (struct FtSocket *)value;
645 
646     FILLP_UNUSED_PARA(inst);
647 
648     /* If it already did close before */
649     if ((sock->allocState != SOCK_ALLOC_STATE_COMM) && (sock->allocState != SOCK_ALLOC_STATE_EPOLL)) {
650         FILLP_LOGINF("Can't close fillp_sock_id:%d,allocState:%d", sock->index, sock->allocState);
651         SET_ERRNO(FILLP_EINVAL);
652         sock->coreErrType[MSG_TYPE_DO_CLOSE] = ERR_UNDERCLOSURE;
653         return;
654     }
655 
656     if ((sock->allocState == SOCK_ALLOC_STATE_EPOLL) || (sock->allocState == SOCK_ALLOC_STATE_EPOLL_TO_CLOSE)) {
657         SpungEpollClose(sock);
658         sock->coreErrType[MSG_TYPE_DO_CLOSE] = ERR_OK;
659         return;
660     }
661 
662     /* Application has called FtClose, so remove all epoll events */
663     {
664         struct HlistNode *node = FILLP_NULL_PTR;
665         struct EpItem *epi = FILLP_NULL_PTR;
666 
667         if (SYS_ARCH_SEM_WAIT(&(sock->epollTaskListLock))) {
668             FILLP_LOGERR("Error to wait epollTaskListLock");
669             SET_ERRNO(FILLP_EBUSY);
670             sock->coreErrType[MSG_TYPE_DO_CLOSE] = ERR_COMM;
671             return;
672         }
673         node = HLIST_FIRST(&sock->epTaskList);
674         while (node != FILLP_NULL_PTR) {
675             epi = EpitemEntrySockWaitNode(node);
676             epi->event.events = 0;
677             node = node->next;
678         }
679 
680         (void)SYS_ARCH_SEM_POST(&(sock->epollTaskListLock));
681     }
682 
683     conn = sock->netconn;
684     conn->closeSet = 1;
685     sock->allocState = SOCK_ALLOC_STATE_WAIT_TO_CLOSE;
686 
687     FillpDfxSockLinkAndQosNotify(sock, FILLP_DFX_LINK_CLOSE);
688     SpungeShutdownSock(sock, SPUNGE_SHUT_RDWR);
689 
690     SpungeCloseMsgFreeSrc(conn, sock);
691 
692     sock->coreErrType[MSG_TYPE_DO_CLOSE] = ERR_OK;
693 }
694 
SpungeHandleMsgSetSendBuf(void * value,struct SpungeInstance * inst)695 static void SpungeHandleMsgSetSendBuf(void *value, struct SpungeInstance *inst)
696 {
697     struct FtSocket *sock = FILLP_NULL_PTR;
698     struct SockOsSocket *osSock = FILLP_NULL_PTR;
699     int sysosSocket;
700     FILLP_INT ret;
701     FILLP_UNUSED_PARA(inst);
702 
703     if (value == FILLP_NULL_PTR) {
704         FILLP_LOGERR("SpungeHandleMsgSetSendBuf value is NULL");
705         return;
706     }
707 
708     sock = (struct FtSocket *)value;
709     osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
710     if (!OS_SOCK_OPS_FUNC_VALID(osSock, getOsSocket)) {
711         sock->coreErrType[MSG_TYPE_SET_SEND_BUF] = ERR_PARAM;
712         FILLP_LOGERR("fillp_sock_id:%d Failed to set the send Buffer size for system socket : not allocated",
713             sock->index);
714         return;
715     }
716 
717     sysosSocket = osSock->ioSock->ops->getOsSocket(osSock->ioSock);
718     ret = SysArchSetSockSndbuf(sysosSocket, sock->resConf.common.udpSendBufSize);
719     if (ret != ERR_OK) {
720         sock->coreErrType[MSG_TYPE_SET_SEND_BUF] = ERR_FAILURE;
721         FILLP_LOGERR("fillp_sock_id:%d Failed to set the send Buffer size for syssocketId = %d",
722             sock->index, sysosSocket);
723         return;
724     }
725 
726     sock->coreErrType[MSG_TYPE_SET_SEND_BUF] = ERR_OK;
727 }
728 
SpungeHandleMsgSetRecvBuf(void * value,struct SpungeInstance * inst)729 static void SpungeHandleMsgSetRecvBuf(void *value, struct SpungeInstance *inst)
730 {
731     struct FtSocket *sock = FILLP_NULL_PTR;
732     struct SockOsSocket *osSock = FILLP_NULL_PTR;
733     FILLP_INT ret;
734     int sysosSocket;
735     FILLP_UNUSED_PARA(inst);
736 
737     if (value == FILLP_NULL_PTR) {
738         FILLP_LOGERR("SpungeHandleMsgSetRecvBuf value is NULL");
739         return;
740     }
741 
742     sock = (struct FtSocket *)value;
743 
744     osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
745     if (!OS_SOCK_OPS_FUNC_VALID(osSock, getOsSocket)) {
746         sock->coreErrType[MSG_TYPE_SET_RECV_BUF] = ERR_PARAM;
747         FILLP_LOGERR("fillp_sock_id:%d Failed to set the receive Buffer size for system socket : not allocated",
748             sock->index);
749         return;
750     }
751 
752     sysosSocket = osSock->ioSock->ops->getOsSocket(osSock->ioSock);
753     ret = SysArchSetSockRcvbuf(sysosSocket, sock->resConf.common.recvBufSize);
754     if (ret != ERR_OK) {
755         sock->coreErrType[MSG_TYPE_SET_RECV_BUF] = ERR_FAILURE;
756         FILLP_LOGERR("fillp_sock_id:%d Failed to set the receive Buffer size for syssocketId = %d",
757             sock->index, sysosSocket);
758         return;
759     }
760 
761     sock->coreErrType[MSG_TYPE_SET_RECV_BUF] = ERR_OK;
762 }
763 
SpungeHandleMsgSetNackDelay(void * value,struct SpungeInstance * inst)764 static void SpungeHandleMsgSetNackDelay(void *value, struct SpungeInstance *inst)
765 {
766     struct NackDelayCfg *cfg = FILLP_NULL_PTR;
767     struct HlistNode *pcbNode = FILLP_NULL_PTR;
768     struct SpungePcb *pcb = FILLP_NULL_PTR;
769 
770     if (value == FILLP_NULL_PTR) {
771         FILLP_LOGERR("SpungeHandleMsgSetRecvBuf value is NULL");
772         return;
773     }
774 
775     FILLP_UNUSED_PARA(inst);
776 
777     cfg = (struct NackDelayCfg *)value;
778 
779     if (cfg->nackCfgVal) {
780         pcbNode = HLIST_FIRST(&SPUNGE_GET_CUR_INSTANCE()->pcbList.list);
781         while (pcbNode != FILLP_NULL_PTR) {
782             pcb = SpungePcbListNodeEntry(pcbNode);
783             pcbNode = pcbNode->next;
784             pcb->fpcb.delayNackTimerNode.interval = (FILLP_UINT32)cfg->nackDelayTimeout;
785             if ((((struct FtNetconn *)pcb->conn)->state == CONN_STATE_CONNECTED) ||
786                 ((struct FtNetconn *)pcb->conn)->state == CONN_STATE_CLOSING) {
787                 FillpEnableDelayNackTimer(&pcb->fpcb);
788             } else {
789                 /* update socket config */
790                 ((struct FtSocket *)(((struct FtNetconn *)pcb->conn)->sock))->resConf.common.nackDelayTimeout =
791                     (FILLP_UINT32)cfg->nackDelayTimeout;
792             }
793         }
794     }
795 
796     SpungeFree(cfg, SPUNGE_ALLOC_TYPE_MALLOC);
797 }
798 
SpungeHandleMsgGetEvtInfo(void * value,struct SpungeInstance * inst)799 static void SpungeHandleMsgGetEvtInfo(void *value, struct SpungeInstance *inst)
800 {
801     struct FtSocket *sock = FILLP_NULL_PTR;
802     FtEventCbkInfo *info = FILLP_NULL_PTR;
803     struct SpungeEvtInfoMsg *msg = FILLP_NULL_PTR;
804 
805     if (value == FILLP_NULL_PTR) {
806         FILLP_LOGERR("value is NULL");
807         return;
808     }
809 
810     FILLP_UNUSED_PARA(inst);
811     msg = (struct SpungeEvtInfoMsg *)value;
812     sock = (struct FtSocket *)msg->sock;
813     info = msg->info;
814 
815     FILLP_UNUSED_PARA(info);
816     sock->coreErrType[MSG_TYPE_GET_EVENT_INFO] = ERR_PARAM;
817 }
818 
SpungeHandleMsgSetKeepAlive(void * value,struct SpungeInstance * inst)819 static void SpungeHandleMsgSetKeepAlive(void *value, struct SpungeInstance *inst)
820 {
821     struct FtSocket *sock = FILLP_NULL_PTR;
822 
823     if (value == FILLP_NULL_PTR) {
824         FILLP_LOGERR("value is NULL");
825         return;
826     }
827 
828     FILLP_UNUSED_PARA(inst);
829     sock = (struct FtSocket *)value;
830     if (sock->netconn != FILLP_NULL_PTR && sock->netconn->pcb != FILLP_NULL_PTR &&
831         sock->netconn->state == CONN_STATE_CONNECTED) {
832         struct FillpPcb *pcb = &sock->netconn->pcb->fpcb;
833         FillpDisableKeepAliveTimer(pcb);
834         pcb->keepAliveTimerNode.interval = FILLP_UTILS_MS2US(sock->resConf.common.keepAliveTime);
835         FillpEnableKeepAliveTimer(pcb);
836         FILLP_LOGINF("set the keepalive interval to %u ms", sock->resConf.common.keepAliveTime);
837     }
838 
839     sock->coreErrType[MSG_TYPE_SET_KEEP_ALIVE] = ERR_OK;
840 }
841 
SpungeHandleMsgSetHiEventCb(void * value,struct SpungeInstance * inst)842 static void SpungeHandleMsgSetHiEventCb(void *value, struct SpungeInstance *inst)
843 {
844     struct SpungeHiEventCbMsg *msg = (struct SpungeHiEventCbMsg *)value;
845     if (value == FILLP_NULL_PTR) {
846         FILLP_LOGERR("value is NULL");
847         return;
848     }
849     FILLP_UNUSED_PARA(inst);
850     FillpDfxDoEvtCbSet(msg->softObj, msg->cb);
851 }
852 
853 /*
854 Description: Message handler
855 Value Range: None
856 Access: Message handler to handle different types of messages like alloc socket, free socket, etc.,
857 Remarks:
858 */
859 spungeMsgHandler g_msgHandler[MSG_TYPE_END] = {
860     SpungeHandleMsgAllocSock,               /* MSG_TYPE_ALLOC_SOCK  */
861     SpungeHandleMsgFreeSockEagain,          /* MSG_TYPE_FREE_SOCK_EAGAIN */
862     SpungeHandleMsgListen,                  /* MSG_TYPE_DO_LISTEN */
863     SpungeHandleMsgConnect,                 /* MSG_TYPE_DO_CONNECT */
864     SpungeHandleMsgBind,                    /* MSG_TYPE_DO_BIND */
865     SpungeHandleMsgConnAccepted,            /* MSG_TYPE_NETCONN_ACCPETED */
866     SpungeHandleMsgClose,                   /* MSG_TYPE_DO_CLOSE */
867     SpungeHandleMsgDoShutdown,              /* MSG_TYPE_DO_SHUTDOWN */
868     SpungeHandleMsgSetSendBuf,              /* MSG_TYPE_SET_SEND_BUF */
869     SpungeHandleMsgSetRecvBuf,              /* MSG_TYPE_SET_RECV_BUF */
870     SpungeHandleMsgSetNackDelay,            /* MSG_TYPE_SET_NACK_DELAY */
871     SpungeHandleMsgGetEvtInfo,              /* MSG_TYPE_GET_EVENT_INFO */
872     SpungeHandleMsgSetKeepAlive,            /* MSG_TYPE_SET_KEEP_ALIVE */
873     SpungeHandleMsgSetHiEventCb,            /* MSG_TYPE_SET_HIEVENT_CB */
874 };
875 
SpungeMsgCreatePoolCb(DympItemType * item)876 static FILLP_INT SpungeMsgCreatePoolCb(DympItemType *item)
877 {
878     FILLP_INT ret;
879     struct SpungeMsg *msg = (struct SpungeMsg *)DYMP_ITEM_DATA(item);
880     ret = SYS_ARCH_SEM_INIT(&msg->syncSem, 0);
881     if (ret != FILLP_OK) {
882         FILLP_LOGERR("SpungeMsgCreatePoolCb:SYS_ARCH_SEM_INIT fails ALARM !! \r\n");
883     }
884 
885     return ret;
886 }
887 
SpungeMsgDestroyPoolCb(DympItemType * item)888 static void SpungeMsgDestroyPoolCb(DympItemType *item)
889 {
890     FILLP_INT ret;
891     struct SpungeMsg *msg = (struct SpungeMsg *)DYMP_ITEM_DATA(item);
892     ret = SYS_ARCH_SEM_DESTROY(&msg->syncSem);
893     if (ret != FILLP_OK) {
894         FILLP_LOGERR("sys arch sem destroy failed ALARM !!\n");
895     }
896 }
897 
SpungeMsgCreatePool(int initSize,int maxSize)898 void *SpungeMsgCreatePool(int initSize, int maxSize)
899 {
900     DympoolItemOperaCbSt itemOperaCb = {SpungeMsgCreatePoolCb, SpungeMsgDestroyPoolCb};
901     return DympCreatePool(initSize, maxSize, sizeof(struct SpungeMsg), FILLP_TRUE,
902                           &itemOperaCb);
903 }
904 
SpungeMsgPoolDestroy(DympoolType * msgPool)905 void SpungeMsgPoolDestroy(DympoolType *msgPool)
906 {
907     DympDestroyPool(msgPool);
908 }
909 
910 #ifdef __cplusplus
911 }
912 #endif /* __cplusplus */
913