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