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