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_app.h"
17 #include "spunge.h"
18 #include "socket_common.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
SpungeInitSocket(struct FtSocket * sock)24 static FILLP_INT SpungeInitSocket(struct FtSocket *sock)
25 {
26     FILLP_INT i;
27     sock->netconn = FILLP_NULL_PTR;
28     (void)memset_s(sock->coreErrType, sizeof(sock->coreErrType), 0, sizeof(sock->coreErrType));
29 
30     sock->listenBacklog = 0;
31     sock->acceptBox = FILLP_NULL_PTR;
32     sock->listenNode.next = FILLP_NULL_PTR;
33     sock->listenNode.pprev = FILLP_NULL_PTR;
34 
35     sock->recvPktBuf = FILLP_NULL_PTR;
36     sock->inst = &g_spunge->instPool[0]; /* Alloc should be always in the first instance */
37     sock->traceHandle = FILLP_NULL_PTR;
38 
39     (void)SYS_ARCH_ATOMIC_SET(&sock->rcvEvent, 0);
40     (void)SYS_ARCH_ATOMIC_SET(&sock->epollWaiting, 0);
41 
42     /* If socket added to epoll without connect, should report out|err|hup */
43     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEvent, 1);
44     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEventCount, 1);
45     sock->errEvent = SPUNGE_EPOLLHUP;
46 
47     sock->eventEpoll = FILLP_NULL_PTR;
48 
49     sock->associatedEpollInstanceIdx = 0;
50     HLIST_INIT(&sock->epTaskList);
51     /* Scan the epoll instance list to which this ft_socket is associated with */
52     for (i = 0; i < FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED; i++) {
53         sock->associatedEpollInstanceArr[i] = FILLP_INVALID_INT;
54     }
55 
56     sock->offset = 0;
57 
58     sock->dataOptionFlag = 0;
59     if (g_appResource.common.enableDateOptTimestamp) {
60         (void)SockUpdatePktDataOpt(sock, (FILLP_UINT16)FILLP_OPT_FLAG_TIMESTAMP, 0);
61     }
62     sock->transmit = 0;
63     sock->jitter = 0;
64     sock->sockAddrType = AF_INET;
65     sock->flags = 0;
66 
67     sock->isListenSock = FILLP_FALSE;
68     sock->traceFlag = FILLP_FALSE;
69     sock->isSockBind = FILLP_FALSE;
70     SockSetNonblocking(sock, FILLP_FALSE);
71     sock->freeTimeCount = FILLP_NULL_NUM;
72     (void)memcpy_s(&sock->resConf, sizeof(struct GlobalAppResource), &g_appResource, sizeof(struct GlobalAppResource));
73     (void)memset_s(&sock->fillpLinger, sizeof(sock->fillpLinger), 0, sizeof(sock->fillpLinger));
74     sock->directlySend = 0;
75 
76     /* post here, so that now sock close can acquire lock */
77     if (SYS_ARCH_SEM_POST(&sock->sockCloseProtect) != ERR_OK) {
78         return ERR_FAILURE;
79     }
80 
81     return ERR_OK;
82 }
83 
SpungeAllocSock(FILLP_INT allocType)84 struct FtSocket *SpungeAllocSock(FILLP_INT allocType)
85 {
86     struct FtSocket *sock = FILLP_NULL_PTR;
87 
88     if ((g_spunge == FILLP_NULL_PTR) || (!g_spunge->hasInited) || (g_spunge->sockTable == FILLP_NULL_PTR)) {
89         FILLP_LOGERR("FILLP Not yet Initialized");
90         return FILLP_NULL_PTR;
91     }
92 
93     if (allocType != SOCK_ALLOC_STATE_COMM && allocType != SOCK_ALLOC_STATE_EPOLL) {
94         FILLP_LOGERR("Wrong Socket Alloc Type");
95         return FILLP_NULL_PTR;
96     }
97 
98     sock = SockAllocSocket();
99     if (sock == FILLP_NULL_PTR) {
100         FILLP_LOGERR("sockets not available from the sockTable->freeQueqe");
101         return FILLP_NULL_PTR;
102     }
103 
104     if (SpungeInitSocket(sock) != ERR_OK) {
105         SockFreeSocket(sock);
106         return FILLP_NULL_PTR;
107     }
108 
109     sock->allocState = allocType;
110 
111     return sock;
112 }
113 
SpungeDelEpInstFromFtSocket(struct FtSocket * sock,FILLP_INT epFd)114 void SpungeDelEpInstFromFtSocket(struct FtSocket *sock, FILLP_INT epFd)
115 {
116     FILLP_INT i;
117     FILLP_INT j;
118     FILLP_INT next;
119 
120     for (i = 0; i < FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED; i++) {
121         if (sock->associatedEpollInstanceArr[i] == epFd) {
122             break;
123         }
124     }
125 
126     for (j = i; j < FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED; j++) {
127         if (j == (FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED - 1)) {
128             sock->associatedEpollInstanceArr[j] = FILLP_INVALID_INT;
129             break;
130         }
131         next = j + 1;
132         sock->associatedEpollInstanceArr[j] = sock->associatedEpollInstanceArr[next];
133     }
134 
135     if (sock->associatedEpollInstanceIdx > 0) {
136         sock->associatedEpollInstanceIdx--;
137     }
138 }
139 
140 #ifdef __cplusplus
141 }
142 #endif
143