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 "epoll_app.h"
17 #include "spunge_app.h"
18 #include "res.h"
19 #include "fillp_flow_control.h"
20 #include "spunge_message.h"
21 #include "socket_common.h"
22 #include "fillp_common.h"
23 #include "spunge_stack.h"
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
SpungeAllocSystemSocket(FILLP_INT domain,FILLP_INT type,FILLP_INT protocol)29 struct SockOsSocket *SpungeAllocSystemSocket(FILLP_INT domain, FILLP_INT type, FILLP_INT protocol)
30 {
31 struct SpungeInstance *curInst = SPUNGE_GET_CUR_INSTANCE();
32 struct SockOsSocket *osSock;
33
34 osSock = (struct SockOsSocket *)SpungeAlloc(1, sizeof(struct SockOsSocket), SPUNGE_ALLOC_TYPE_CALLOC);
35 if (osSock == FILLP_NULL_PTR) {
36 FILLP_LOGERR("Failed to allocate memory for os socket \r\n");
37
38 return FILLP_NULL_PTR;
39 }
40
41 osSock->reference = 0;
42 osSock->addrType = domain;
43
44 osSock->ioSock = SysIoSocketFactory(domain, type, protocol);
45 if (osSock->ioSock == FILLP_NULL_PTR) {
46 FILLP_LOGERR("Alloc osSock fail");
47 SpungeFree(osSock, SPUNGE_ALLOC_TYPE_CALLOC);
48 osSock = FILLP_NULL_PTR;
49 return osSock;
50 }
51
52 HLIST_INIT_NODE(&osSock->osListNode);
53 HlistAddTail(&curInst->osSockist, &osSock->osListNode);
54
55 return osSock;
56 }
57
SpungeEpollFreeResource(struct FtSocket * sock)58 static void SpungeEpollFreeResource(struct FtSocket *sock)
59 {
60 FILLP_UINT32 i;
61
62 HLIST_INIT(&sock->epTaskList);
63
64 if (sock->eventEpoll != FILLP_NULL_PTR) {
65 (void)SYS_ARCH_SEM_DESTROY(&sock->eventEpoll->waitSem);
66
67 (void)SYS_ARCH_SEM_DESTROY(&sock->eventEpoll->appCoreSem);
68
69 (void)SYS_ARCH_SEM_DESTROY(&sock->eventEpoll->appSem);
70 }
71
72 /* Scan the epoll instance list to which this FtSocket is associated with */
73 for (i = 0; i < FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED; i++) {
74 /* Delete happens from higher array index to lower array index. So until
75 the 0th index is cleared, continue to remove epoll instance
76 */
77 if (sock->associatedEpollInstanceArr[0] != FILLP_INVALID_INT) {
78 struct FtSocket *epollSock = FILLP_NULL_PTR;
79 FILLP_INT assIdex = sock->associatedEpollInstanceArr[0];
80
81 if ((assIdex < 0) || (assIdex >= SYS_ARCH_ATOMIC_READ(&g_spunge->sockTable->used))) {
82 /* Socket index is not in range, skip and continue */
83 continue;
84 }
85
86 epollSock = g_spunge->sockTable->sockPool[assIdex];
87
88 if (epollSock->allocState == SOCK_ALLOC_STATE_FREE) {
89 SpungeDelEpInstFromFtSocket(sock, assIdex);
90
91 /* Socket state is in free state, skip and continue */
92 continue;
93 }
94
95 (void)SpungeEpollFindRemove(sock->associatedEpollInstanceArr[0], sock->index);
96 }
97 }
98
99 sock->associatedEpollInstanceIdx = 0;
100
101 (void)SYS_ARCH_ATOMIC_SET(&sock->rcvEvent, 0);
102 (void)SYS_ARCH_ATOMIC_SET(&sock->sendEvent, 0);
103 (void)SYS_ARCH_ATOMIC_SET(&sock->sendEventCount, 0);
104 sock->errEvent = 0;
105
106 return;
107 }
108
SpungeFreeAcceptBox(struct FtSocket * sock)109 void SpungeFreeAcceptBox(struct FtSocket *sock)
110 {
111 FILLP_INT i;
112 struct FtNetconn *conn = FILLP_NULL_PTR;
113 int count;
114
115 for (i = 0; i < SPUNGE_SOCKET_BOX_SIZE; i++) {
116 count = FillpQueuePop(sock->acceptBox, (void *)&conn, 1);
117 if (count > 0) {
118 FillpNetconnDestroy(conn);
119 } else {
120 break;
121 }
122 }
123
124 FillpQueueDestroy(sock->acceptBox);
125 sock->acceptBox = FILLP_NULL_PTR;
126 return;
127 }
128
SpungeIncFreeCntPostEagain(struct FtSocket * sock)129 void SpungeIncFreeCntPostEagain(struct FtSocket *sock)
130 {
131 FillpErrorType ret;
132 sock->freeTimeCount++;
133 FILLP_LOGDBG("fillp_sock_id:%d,sock->freeTimeCount:%d, errno:%d",
134 sock->index, sock->freeTimeCount, FT_OS_GET_ERRNO);
135
136 ret = SpungePostMsg(SPUNGE_GET_CUR_INSTANCE(), (void *)sock, MSG_TYPE_FREE_SOCK_EAGAIN, FILLP_FALSE);
137 if (ret != ERR_OK) {
138 FILLP_LOGERR("FAILED TO POST -- MSG_TYPE_FREE_SOCK_EAGAIN--- to CORE."
139 "Socket leak can happen : Sock ID: %d\r\n", sock->index);
140 }
141
142 return;
143 }
144
RecursiveRbTree(struct RbNode * node)145 static void RecursiveRbTree(struct RbNode *node)
146 {
147 struct RbNode *parent = node;
148 struct EpItem *epi = FILLP_NULL_PTR;
149 struct RbNode *right = FILLP_NULL_PTR;
150 struct FtSocket *sock = FILLP_NULL_PTR;
151 struct RbNode *left = FILLP_NULL_PTR;
152
153 if (node == FILLP_NULL_PTR) {
154 FILLP_LOGERR("RecursiveRbTree: Inavild parameters passed.");
155
156 return;
157 }
158
159 left = (struct RbNode *)(parent->rbLeft);
160
161 if (left != FILLP_NULL_PTR) {
162 RecursiveRbTree(left);
163 }
164
165 right = (struct RbNode *)(parent->rbRight);
166 epi = EpItemEntryRbNode(parent);
167 if (epi == FILLP_NULL_PTR) {
168 FILLP_LOGERR("RecursiveRbTree: EpItemEntryRbNode returns NULL. ");
169
170 return;
171 }
172
173 sock = SockGetSocket(epi->fileDespcriptor);
174 if (sock != FILLP_NULL_PTR) {
175 (void)SYS_ARCH_ATOMIC_DEC(&sock->epollWaiting, 1);
176
177 if (SYS_ARCH_SEM_WAIT(&sock->epollTaskListLock)) {
178 FILLP_LOGERR("Error to wait epoll_task_list");
179 return;
180 }
181 HlistDelNode(&epi->sockWaitNode);
182 DympFree(epi);
183 (void)SYS_ARCH_SEM_POST(&sock->epollTaskListLock);
184 }
185
186 if (right != FILLP_NULL_PTR) {
187 RecursiveRbTree(right);
188 }
189
190 return;
191 }
192
193 /*
194 * @Description : Closes the epoll socket and releases all associated resources.
195 * @param : epoll ft sock index
196 * @return : success: ERR_OK fail: error code
197 * @NOTE: caller must have acquired (wait) the close semaphore to protect from MT scenarios. this
198 * function on completion will post the event back to semaphore once execution is completed.
199 */
SpungEpollClose(struct FtSocket * sock)200 void SpungEpollClose(struct FtSocket *sock)
201 {
202 struct EventPoll *ep = (sock->eventEpoll);
203 struct RbRoot rtNoe;
204 struct RbNode *parent = FILLP_NULL_PTR;
205 SYS_ARCH_RW_SEM *sockConnSem = &sock->sockConnSem;
206
207 if (ep == FILLP_NULL_PTR) {
208 sock->allocState = SOCK_ALLOC_STATE_FREE;
209 FILLP_LOGERR("eventEpoll is NULL. fillp_sock_id:%d", sock->index);
210 return;
211 }
212
213 if (SYS_ARCH_RWSEM_TRYWRWAIT(sockConnSem) != ERR_OK) {
214 int ret;
215 sock->allocState = SOCK_ALLOC_STATE_EPOLL_TO_CLOSE;
216 (void)SYS_ARCH_SEM_POST(&ep->waitSem);
217 ret = SpungePostMsg(SPUNGE_GET_CUR_INSTANCE(), (void *)sock, MSG_TYPE_FREE_SOCK_EAGAIN, FILLP_FALSE);
218 if (ret != ERR_OK) {
219 FILLP_LOGERR("FAILED TO POST -- MSG_TYPE_FREE_SOCK_EAGAIN--- to CORE."
220 "Socket leak can happen : Sock ID: %d", sock->index);
221 }
222 return;
223 }
224
225 rtNoe = ep->rbr;
226 parent = rtNoe.rbNode;
227 if (parent != FILLP_NULL_PTR) {
228 RecursiveRbTree(parent);
229 }
230
231 SpungeEpollFreeResource(sock);
232
233 DympFree(sock->eventEpoll);
234 sock->eventEpoll = FILLP_NULL_PTR;
235
236 sock->flags = 0;
237 sock->traceFlag = 0;
238 sock->allocState = SOCK_ALLOC_STATE_FREE;
239 sock->freeTimeCount = FILLP_NULL_NUM;
240 (void)SYS_ARCH_RWSEM_WRPOST(&sock->sockConnSem);
241
242 (void)FillpQueuePush(g_spunge->sockTable->freeQueqe, (void *)&sock, FILLP_FALSE, 1);
243 return;
244 }
SpungeCloseCBSocket(struct FtSocket * sock)245 static void SpungeCloseCBSocket(struct FtSocket *sock)
246 {
247 if ((FILLP_SOCKETCLOSE_CBK != FILLP_NULL_PTR) && (sock->isListenSock == FILLP_FALSE) &&
248 (sock->netconn != FILLP_NULL_PTR) && (sock->netconn->pcb != FILLP_NULL_PTR) &&
249 (sock->netconn->state == CONN_STATE_CLOSED)) {
250 SysIoUdpSock *udpSock = FILLP_NULL_PTR;
251 struct SockOsSocket *osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
252 if (osSock != FILLP_NULL_PTR) {
253 udpSock = (SysIoUdpSock *)osSock->ioSock;
254 FILLP_SOCKETCLOSE_CBK(udpSock->udpSock, (struct sockaddr *)&sock->netconn->pcb->localAddr,
255 (struct sockaddr *)&sock->netconn->pcb->remoteAddr);
256 }
257 }
258 }
259
SpungeFreeSock(struct FtSocket * sock)260 void SpungeFreeSock(struct FtSocket *sock)
261 {
262 if ((sock == FILLP_NULL_PTR) || (sock->allocState == SOCK_ALLOC_STATE_FREE)) {
263 return;
264 }
265
266 FILLP_LOGDTL("fillp_sock_id:%d", sock->index);
267 FillpErrorType ret = SYS_ARCH_RWSEM_TRYWRWAIT(&sock->sockConnSem);
268 if (ret != ERR_OK) {
269 SpungeIncFreeCntPostEagain(sock);
270 return;
271 }
272
273 if (sock->allocState != SOCK_ALLOC_STATE_EPOLL) {
274 if ((sock->netconn != FILLP_NULL_PTR) && !SpungeConnCheckUnsendBoxEmpty(sock->netconn)) {
275 FILLP_LOGDBG("Unsend Box still not empty, fillp_sock_id:%d", sock->index);
276 SpungeIncFreeCntPostEagain(sock);
277 (void)SYS_ARCH_RWSEM_WRPOST(&sock->sockConnSem);
278 return;
279 }
280 }
281
282 FILLP_LOGINF("spunge_free_start, fillp_sock_id:%d", sock->index);
283 SpungeCloseCBSocket(sock);
284 SpungeEpollFreeResource(sock);
285
286 if (sock->netconn != FILLP_NULL_PTR) {
287 struct SockOsSocket *osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
288 if (OS_SOCK_OPS_FUNC_VALID(osSock, freeSock)) {
289 osSock->ioSock->ops->freeSock((void *)sock, (void *)osSock);
290 }
291 FillpNetconnDestroy(sock->netconn);
292 sock->netconn = FILLP_NULL_PTR;
293 }
294
295 if (sock->acceptBox != FILLP_NULL_PTR) {
296 SpungeFreeAcceptBox(sock);
297 }
298
299 sock->flags = 0;
300 sock->traceFlag = 0;
301 if (sock->isListenSock == FILLP_TRUE) {
302 (void)SYS_ARCH_SEM_DESTROY(&sock->acceptSem);
303 sock->isListenSock = FILLP_FALSE;
304 }
305
306 sock->allocState = SOCK_ALLOC_STATE_FREE;
307 sock->freeTimeCount = FILLP_NULL_NUM;
308
309 (void)FillpQueuePush(g_spunge->sockTable->freeQueqe, (void *)&sock, FILLP_FALSE, 1);
310 (void)SYS_ARCH_RWSEM_WRPOST(&sock->sockConnSem);
311
312 return;
313 }
314
SpungeShutdownSock(void * argSock,FILLP_INT how)315 void SpungeShutdownSock(void *argSock, FILLP_INT how)
316 {
317 struct FtSocket *sock = (struct FtSocket *)argSock;
318 struct FtNetconn *netconn = sock->netconn;
319 FILLP_INT connState;
320
321 if (netconn == FILLP_NULL_PTR) {
322 FILLP_LOGERR("sock->netconn is NULL");
323 return;
324 }
325
326 connState = NETCONN_GET_STATE(netconn);
327 FILLP_LOGINF("Shutdown,fillp_sock_id:%d,connState:%d", sock->index, connState);
328
329 if (((how == SPUNGE_SHUT_RD) || (how == SPUNGE_SHUT_RDWR)) && !netconn->shutdownRdSet) {
330 netconn->shutdownRdSet = 1;
331 #ifdef SOCK_RECV_SEM
332 (void)SYS_ARCH_SEM_POST(&SOCK_GET_RECVSEM(sock));
333 #endif /* SOCK_RECV_SEM */
334
335 if (sock->isListenSock == FILLP_TRUE) {
336 (void)SYS_ARCH_SEM_POST(&sock->acceptSem);
337 }
338 }
339
340 if (((how == SPUNGE_SHUT_WR) || (how == SPUNGE_SHUT_RDWR)) && !netconn->shutdownWrSet) {
341 netconn->shutdownWrSet = 1;
342 (void)SYS_ARCH_SEM_POST(&SOCK_GET_SENDSEM(sock));
343 }
344 }
345
SpungeConnCheckUnsendBoxEmpty(struct FtNetconn * conn)346 FILLP_BOOL SpungeConnCheckUnsendBoxEmpty(struct FtNetconn *conn)
347 {
348 FILLP_ULLONG con;
349 FILLP_ULLONG prod;
350 void *data = FILLP_NULL_PTR;
351 struct FillpPcbItem *item = FILLP_NULL_PTR;
352 FillpQueue *unsendBox = FILLP_NULL_PTR;
353
354 if ((conn == FILLP_NULL_PTR) || (conn->pcb == FILLP_NULL_PTR)) {
355 FILLP_LOGERR("NULL Pointer");
356 return FILLP_TRUE;
357 }
358 unsendBox = conn->pcb->fpcb.send.unsendBox;
359
360 if (unsendBox == FILLP_NULL_PTR) {
361 return FILLP_TRUE;
362 }
363
364 con = unsendBox->ring.cons.head + 1;
365 prod = unsendBox->ring.prod.tail;
366
367 while (((FILLP_LLONG)(prod - con)) >= 0) {
368 data = unsendBox->ring.ringCache[con % unsendBox->ring.size];
369 con++;
370
371 if (data == FILLP_NULL_PTR) {
372 continue;
373 }
374
375 item = (struct FillpPcbItem *)data;
376 if (item->netconn == (void *)conn) {
377 FILLP_LOGDBG("Still has data in unsedn box");
378 return FILLP_FALSE;
379 }
380 }
381
382 return FILLP_TRUE;
383 }
384
SpungeDestroyNoWait(struct FillpPcb * pcb,struct FtSocket * sock,struct FtNetconn * conn)385 static int SpungeDestroyNoWait(struct FillpPcb *pcb, struct FtSocket *sock, struct FtNetconn *conn)
386 {
387 #if FILLP_DEFAULT_DESTROY_STACK_WITHOUT_WAIT_SOCKET_CLOSE
388 /* for miracast, ignore the unSend unAck and unRecv packets, skip the disconnection flow,
389 because app will call FtClose once wifi disconnect, stack can't free socket until
390 10s keep alive timeout. That would lead FtDestroy block a long time. */
391 if (pcb->pcbInst->waitTobeCoreKilled == FILLP_TRUE) {
392 FILLP_LOGERR("ignore unsend packet, skip dissconnetion flow and about to free socket %d", sock->index);
393 SpungeConnClosed(conn);
394 return 1;
395 }
396 #endif
397 return 0;
398 }
399
SpungeCheckDisconn(void * argConn)400 void SpungeCheckDisconn(void *argConn)
401 {
402 struct FtNetconn *conn = (struct FtNetconn *)argConn;
403 struct FtSocket *sock = (struct FtSocket *)conn->sock;
404 struct FillpPcb *pcb = FILLP_NULL_PTR;
405 FILLP_UINT8 connState;
406 struct FillpSendPcb *sendPcb = FILLP_NULL_PTR;
407
408 if (sock == FILLP_NULL_PTR || conn->pcb == FILLP_NULL_PTR) {
409 FILLP_LOGERR("NULL pointer sock or conn->pcb");
410 return;
411 }
412
413 pcb = &conn->pcb->fpcb;
414
415 connState = NETCONN_GET_STATE(conn);
416 FILLP_LOGDBG("fillp_sock_id:%d", sock->index);
417 if (!(connState == CONN_STATE_CONNECTED || connState == CONN_STATE_CLOSING)) {
418 FILLP_LOGERR("No need to check disconn message anymore,fillp_sock_id:%d,connState:%u",
419 sock->index, connState);
420 return;
421 }
422
423 if (connState == CONN_STATE_CONNECTED) {
424 /* Check all unsend box */
425 if (!SpungeConnCheckUnsendBoxEmpty(conn)) {
426 goto TIMER_REPEAT;
427 }
428
429 if (SpungeDestroyNoWait(pcb, sock, conn) != 0) {
430 return;
431 }
432 /* Check if all send data are sent out */
433 sendPcb = &conn->pcb->fpcb.send;
434 FillpAckSendPcb(&conn->pcb->fpcb, 0);
435
436 if ((sock->lingering == FILLP_FALSE) && (sendPcb->unackList.count ||
437 sendPcb->unrecvList.nodeNum || !HLIST_EMPTY(&sendPcb->unSendList) ||
438 sendPcb->itemWaitTokenLists.nodeNum || sendPcb->redunList.nodeNum)) {
439 FILLP_LOGDBG("Still has data to send");
440 goto TIMER_REPEAT;
441 }
442
443 FILLP_LOGINF("Now all unSend data are checked.Going to send fin fillp_sock_id:%d", sock->index);
444 conn->sendBufRunOut = FILLP_TRUE;
445 /* Need to reconsider the disconn message send */
446 FillpNetconnSetState(conn, CONN_STATE_CLOSING);
447 pcb->finCheckTimer.interval =
448 (FILLP_UINT32)FILLP_UTILS_MS2US((FILLP_LLONG)sock->resConf.common.disconnectRetryTimeout);
449 } else if (SpungeDestroyNoWait(pcb, sock, conn) != 0) {
450 return;
451 }
452
453 if (pcb->isFinAckReceived != FILLP_TRUE) {
454 FillpSendFin(pcb);
455 }
456
457 TIMER_REPEAT:
458 FillpEnableFinCheckTimer(pcb);
459 return;
460 }
461
SpungeSendConnectMsg(void * argConn)462 void SpungeSendConnectMsg(void *argConn)
463 {
464 struct FtNetconn *conn = (struct FtNetconn *)argConn;
465 struct FtSocket *sock = (struct FtSocket *)conn->sock;
466 struct SockOsSocket *osSock = FILLP_NULL_PTR;
467 FILLP_UINT8 connState = NETCONN_GET_STATE(conn);
468 if (connState != CONN_STATE_CONNECTING) {
469 FILLP_LOGINF("socket state = %u is not in connecting state for the conn",
470 connState);
471 return;
472 }
473
474 if (NetconnIsConnectTimeout(conn)) {
475 if (sock == FILLP_NULL_PTR) {
476 FILLP_LOGWAR("connection state idle for the conn");
477
478 /* No need to stop the conenct timer again, as it is already stopped upon earlier socket_clear */
479 return;
480 }
481
482 FillpNetconnSetState(conn, CONN_STATE_IDLE);
483 SET_ERRNO(FILLP_ETIMEDOUT);
484 sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_CONN_TIMEOUT;
485 if (SOCK_IS_NONBLOCKING(sock)) {
486 FILLP_SOCK_SET_ERR(sock, FILLP_ECONNREFUSED);
487 FillpNetconnSetSafeErr(conn, ERR_CONNREFUSED);
488 } else {
489 FillpNetconnSetSafeErr(conn, ERR_CONN_TIMEOUT);
490 }
491
492 SpungeConnConnectFail(conn->sock);
493
494 return;
495 }
496
497 FillpEnableConnRetryCheckTimer(&conn->pcb->fpcb);
498
499 osSock = NETCONN_GET_OSSOCK(conn, SPUNGE_GET_CUR_INSTANCE()->instIndex);
500 if (!OS_SOCK_OPS_FUNC_VALID(osSock, connected) || !OS_SOCK_OPS_FUNC_VALID(osSock, sendPacket)) {
501 FILLP_LOGERR("osSock is NULL");
502 return;
503 }
504 osSock->ioSock->ops->connected(sock, osSock->ioSock);
505 if (osSock->ioSock->ops->sendPacket(
506 FILLP_PKT_TYPE_CONN_REQ, (void *)osSock->ioSock, (void *)conn->pcb, FILLP_NULL_PTR) == -1) {
507 FILLP_LOGINF("send conn req fail for sockId:%d", sock->index);
508 }
509
510 return;
511 }
512
SpinstAddToPcbList(struct SpungeInstance * inst,struct HlistNode * node)513 void SpinstAddToPcbList(struct SpungeInstance *inst, struct HlistNode *node)
514 {
515 HlistAddTail(&inst->pcbList.list, node);
516 }
517
SpinstDeleteFromPcbList(struct SpungeInstance * inst,struct HlistNode * node)518 void SpinstDeleteFromPcbList(struct SpungeInstance *inst, struct HlistNode *node)
519 {
520 HlistDelete(&inst->pcbList.list, node);
521 }
522
SpungeAllocUnsendBox(struct SpungeInstance * inst)523 FillpQueue *SpungeAllocUnsendBox(struct SpungeInstance *inst)
524 {
525 return inst->unsendBox[0];
526 }
527
SpungeFreeUnsendBox(struct FillpPcb * pcb)528 void SpungeFreeUnsendBox(struct FillpPcb *pcb)
529 {
530 FILLP_UNUSED_PARA(pcb);
531 return;
532 }
533
534 /* This function is called when the connection is sure closed
535 For : 1) close() involked and rst send out
536 2) recved rst from peer
537 3) disconnect send out and disconn recved (local and peer send disconnect both)
538 if close() involked, the recv box data will be dropped, or the recv() still returns positive if data remains,
539 return 0 if all data taken
540 */
SpungeConnClosed(struct FtNetconn * conn)541 void SpungeConnClosed(struct FtNetconn *conn)
542 {
543 if (NETCONN_GET_STATE(conn) == CONN_STATE_CLOSED) {
544 FILLP_LOGERR("Already closed");
545 return;
546 }
547
548 if (conn->sock == FILLP_NULL_PTR) {
549 FILLP_LOGERR("conn socket is NULL");
550 return;
551 }
552
553 if (conn->pcb == FILLP_NULL_PTR) {
554 FILLP_LOGERR("conn pcb is NULL");
555 return;
556 }
557
558 FILLP_LOGINF("fillp_sock_id:%d", ((struct FtSocket *)conn->sock)->index);
559
560 FillpNetconnSetState(conn, CONN_STATE_CLOSED);
561 FillpPcbRemoveTimers(&conn->pcb->fpcb);
562
563 if (conn->closeSet) {
564 /* Try to release the recv box data */
565 if (SpungePostMsg(SPUNGE_GET_CUR_INSTANCE(), (void *)((struct FtSocket *)conn->sock),
566 MSG_TYPE_FREE_SOCK_EAGAIN, FILLP_FALSE) != ERR_OK) {
567 FILLP_LOGERR("FAILED TO POST -- MSG_TYPE_FREE_SOCK_EAGAIN--- to CORE"
568 " Sock ID: %d", ((struct FtSocket*)conn->sock)->index);
569 }
570 }
571 }
572
SpungeConnConnectSuccess(void * argSock)573 void SpungeConnConnectSuccess(void *argSock)
574 {
575 struct FtSocket *sock = (struct FtSocket *)argSock;
576 if (!SOCK_IS_NONBLOCKING(sock)) {
577 (void)SYS_ARCH_SEM_POST(&sock->connBlockSem);
578 }
579
580 sock->errEvent = 0;
581 SpungeEpollEventCallback(sock, SPUNGE_EPOLLOUT, 1);
582 }
583
SpungeConnConnectFail(void * argSock)584 void SpungeConnConnectFail(void *argSock)
585 {
586 struct FtSocket *sock = (struct FtSocket *)argSock;
587 if (!SOCK_IS_NONBLOCKING(sock)) {
588 (void)SYS_ARCH_SEM_POST(&sock->connBlockSem);
589 }
590 sock->errEvent |= (FILLP_UINT32)SPUNGE_EPOLLHUP;
591 SpungeEpollEventCallback(sock, (FILLP_INT)SPUNGE_EPOLLOUT | (FILLP_INT)SPUNGE_EPOLLHUP, 1);
592 }
593
594 #ifdef __cplusplus
595 }
596 #endif
597