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