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 "socket_app.h"
17 #include "spunge_app.h"
18 #include "fillp_buf_item.h"
19 #include "spunge_message.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
SockSetError(struct FtSocket * sock,FillpErrorType err)25 static void SockSetError(struct FtSocket *sock, FillpErrorType err)
26 {
27     switch (err) {
28         case ERR_NONBLOCK_UNDERCONNECT:
29             FILLP_SOCK_SET_ERR(sock, FILLP_EINPROGRESS);
30             SET_ERRNO(FILLP_EINPROGRESS);
31             break;
32 
33         case ERR_CONN_TIMEOUT:
34             FILLP_SOCK_SET_ERR(sock, FILLP_ETIMEDOUT);
35             SET_ERRNO(FILLP_ETIMEDOUT);
36             break;
37 
38         case FILLP_ERR_ISCONN:
39         case ERR_REMOTE_REJECT_OR_CLOSE:
40             FILLP_SOCK_SET_ERR(sock, FILLP_EISCONN);
41             SET_ERRNO(FILLP_EISCONN);
42             break;
43 
44         case ERR_CONNREFUSED:
45             FILLP_SOCK_SET_ERR(sock, FILLP_ECONNREFUSED);
46             SET_ERRNO(FILLP_ECONNREFUSED);
47             break;
48 
49         case FILLP_ERR_EALREADY:
50             FILLP_SOCK_SET_ERR(sock, FILLP_EALREADY);
51             SET_ERRNO(FILLP_EALREADY);
52             break;
53 
54         case ERR_PARAM:
55             FILLP_SOCK_SET_ERR(sock, FILLP_EINVAL);
56             SET_ERRNO(FILLP_EINVAL);
57             break;
58 
59         case ERR_WRONGSTATE:
60             FILLP_SOCK_SET_ERR(sock, FILLP_ENOTCONN);
61             SET_ERRNO(FILLP_ENOTCONN);
62             break;
63 
64         case ERR_FAILURE:
65             FILLP_SOCK_SET_ERR(sock, FILLP_EFAULT);
66             SET_ERRNO(FILLP_EFAULT);
67             break;
68 
69         case ERR_SYSTEM_MEMORY_FAILURE:
70             FILLP_SOCK_SET_ERR(sock, FILLP_ENOMEM);
71             SET_ERRNO(FILLP_ENOMEM);
72             break;
73 
74         default:
75             FILLP_SOCK_SET_ERR(sock, FILLP_ENOBUFS);
76             SET_ERRNO(FILLP_ENOBUFS);
77             break;
78     }
79 }
80 
SockCheckDomainTypeProto(FILLP_INT domain,FILLP_INT type,FILLP_INT protocol)81 static FILLP_INT SockCheckDomainTypeProto(FILLP_INT domain, FILLP_INT type, FILLP_INT protocol)
82 {
83     if (((domain != PF_INET) && (domain != AF_INET) && (domain != AF_INET6) && (domain != PF_INET6)) ||
84         (type != SOCK_STREAM)) {
85         FILLP_LOGERR("SockCheckDomainTypeProto domain/type/protocol is not correct, "
86                      "domain = %d, type = %d, protocol =%d", domain, type, protocol);
87         if (type != SOCK_STREAM) {
88             SET_ERRNO(FILLP_ESOCKTNOSUPPORT);
89         } else {
90             SET_ERRNO(FILLP_EAFNOSUPPORT);
91         }
92 
93         return -1;
94     }
95 
96     if (protocol != IPPROTO_FILLP) {
97         FILLP_LOGERR("SockCheckDomainTypeProto domain/type/protocol is not correct, "
98                      "domain = %d, type = %d, protocol =%d", domain, type, protocol);
99         SET_ERRNO(FILLP_EPROTONOSUPPORT);
100         return -1;
101     }
102 
103     return ERR_OK;
104 }
105 
SockSocket(FILLP_INT domain,FILLP_INT type,FILLP_INT protocol)106 FILLP_INT SockSocket(FILLP_INT domain, FILLP_INT type, FILLP_INT protocol)
107 {
108     struct FtSocket *sock = FILLP_NULL_PTR;
109     struct SpungeSocketMsg sockMsg;
110     FillpErrorType err;
111     FILLP_LOGINF("domain:%d,type:%d,protocol:%d", domain, type, protocol);
112     if (SockCheckDomainTypeProto(domain, type, protocol) != ERR_OK) {
113         return -1;
114     }
115 
116     /* Connection resource not alloc here , but after do bind or connect action */
117     sock = SpungeAllocSock(SOCK_ALLOC_STATE_COMM);
118     if (sock == FILLP_NULL_PTR) {
119         FILLP_LOGERR("SockSocket: failed to allocate socket");
120         SET_ERRNO(FILLP_EMFILE);
121         return -1;
122     }
123 
124     sockMsg.domain = domain;
125     sockMsg.protocol = protocol;
126     sockMsg.type = type;
127     sock->socketType = type;
128     sock->socketProtocol = protocol;
129     sockMsg.sock = (void *)sock;
130     sock->sockAddrType = (FILLP_UINT16)domain;
131     sock->traceFlag = g_spunge->traceFlag;
132     sock->traceHandle = g_spunge->traceHandle;
133     err = SpungePostMsg(sock->inst, &sockMsg, MSG_TYPE_ALLOC_SOCK, FILLP_TRUE);
134     if (err != ERR_OK) {
135         FILLP_LOGERR("SockSocket: failed to post msg to fillp sock->index = %d\r\n", sock->index);
136         sock->allocState = SOCK_ALLOC_STATE_FREE;
137         SockFreeSocket(sock);
138         SET_ERRNO(FILLP_ENOBUFS);
139         return -1;
140     }
141 
142     if (sock->allocState != SOCK_ALLOC_STATE_COMM) {
143         FILLP_LOGERR("socket state is invalid and no free sockets sock->index = %d\r\n", sock->index);
144         sock->allocState = SOCK_ALLOC_STATE_FREE;
145         SockFreeSocket(sock);
146         SET_ERRNO(sock->coreErrType[MSG_TYPE_ALLOC_SOCK]);
147         return -1;
148     }
149 
150     /* When the socket is inited, then mark the errno for that socket as ERR_OK */
151     FILLP_LOGINF("Sock alloced, fillp_sock_id:%d", sock->index);
152     return sock->index;
153 }
154 
SockSend(FILLP_INT sockIndex,FILLP_CONST void * data,FILLP_SIZE_T size,FILLP_INT flags)155 FILLP_INT SockSend(FILLP_INT sockIndex, FILLP_CONST void *data, FILLP_SIZE_T size, FILLP_INT flags)
156 {
157     return SockSendFrame(sockIndex, data, size, flags, FILLP_NULL_PTR);
158 }
159 
160 #ifdef FILLP_LINUX
161 #define FRAME_CMSG_LEN CMSG_SPACE(sizeof(struct FrameInfo))
SockSendFrameInitCmsg(struct msghdr * m,FILLP_CONST struct FrameInfo * frame)162 static void SockSendFrameInitCmsg(struct msghdr *m, FILLP_CONST struct FrameInfo *frame)
163 {
164     struct cmsghdr *f = CMSG_FIRSTHDR(m);
165     f->cmsg_level = IPPROTO_FILLP;
166     f->cmsg_type = FILLP_CMSG_TYPE_FRAME;
167     f->cmsg_len = CMSG_LEN(sizeof(struct FrameInfo));
168     (void)memcpy_s((FILLP_UINT8 *)CMSG_DATA(f), sizeof(struct FrameInfo), frame, sizeof(struct FrameInfo));
169 }
170 
SockSendSetFrameInfo(struct msghdr * m,FILLP_UINT8 * frameCmsg,size_t frameCmsgLen,FILLP_CONST struct FrameInfo * frame)171 static void SockSendSetFrameInfo(struct msghdr *m, FILLP_UINT8 *frameCmsg, size_t frameCmsgLen,
172     FILLP_CONST struct FrameInfo *frame)
173 {
174     if (frame != FILLP_NULL_PTR) {
175         m->msg_control = (void *)frameCmsg;
176         m->msg_controllen = frameCmsgLen;
177         SockSendFrameInitCmsg(m, frame);
178     } else {
179         m->msg_control = FILLP_NULL_PTR;
180         m->msg_controllen = 0;
181     }
182 }
183 
SockSendGetFrameInfo(struct msghdr * m)184 static FILLP_CONST struct FrameInfo *SockSendGetFrameInfo(struct msghdr *m)
185 {
186     struct cmsghdr *cmsg = FILLP_NULL_PTR;
187 
188     if (m->msg_control == FILLP_NULL_PTR) {
189         return FILLP_NULL_PTR;
190     }
191 
192     for (cmsg = CMSG_FIRSTHDR(m); cmsg != FILLP_NULL_PTR; cmsg = CMSG_NXTHDR(m, cmsg)) {
193         if (cmsg->cmsg_level == IPPROTO_FILLP &&
194             cmsg->cmsg_type == FILLP_CMSG_TYPE_FRAME &&
195             cmsg->cmsg_len == CMSG_LEN(sizeof(struct FrameInfo))) {
196             return (FILLP_CONST struct FrameInfo *)CMSG_DATA(cmsg);
197         }
198     }
199 
200     return FILLP_NULL_PTR;
201 }
202 #else
SockSendSetFrameInfo(struct msghdr * m,FILLP_CONST struct FrameInfo * frame)203 static void SockSendSetFrameInfo(struct msghdr *m, FILLP_CONST struct FrameInfo *frame)
204 {
205     m->msg_control = (void *)frame;
206     m->msg_controllen = (frame == FILLP_NULL_PTR) ? 0 : sizeof(struct FrameInfo);
207 }
208 
SockSendGetFrameInfo(struct msghdr * m)209 static FILLP_CONST struct FrameInfo *SockSendGetFrameInfo(struct msghdr *m)
210 {
211     return (FILLP_CONST struct FrameInfo *)m->msg_control;
212 }
213 #endif
214 
SockSendFrame(FILLP_INT sockIndex,FILLP_CONST void * data,FILLP_SIZE_T size,FILLP_INT flags,FILLP_CONST struct FrameInfo * frame)215 FILLP_INT SockSendFrame(FILLP_INT sockIndex, FILLP_CONST void *data, FILLP_SIZE_T size, FILLP_INT flags,
216         FILLP_CONST struct FrameInfo *frame)
217 {
218     struct iovec msgIov;
219     struct msghdr msg;
220 #ifdef FILLP_LINUX
221     FILLP_UINT8 frameCmsg[FRAME_CMSG_LEN] = {0};
222 #endif
223 
224     if ((data == FILLP_NULL_PTR) || (size == 0)) {
225         FILLP_LOGERR("input data is pointer is null for sock id, fillp_sock_id: %d", sockIndex);
226         SET_ERRNO(FILLP_EINVAL);
227         return -1;
228     }
229 
230     msgIov.iov_base = (void *)data;
231     msgIov.iov_len = size;
232 
233     msg.msg_name = FILLP_NULL_PTR;
234     msg.msg_namelen = 0;
235     msg.msg_iov = &msgIov;
236     msg.msg_iovlen = 1;
237 #ifdef FILLP_LINUX
238     SockSendSetFrameInfo(&msg, frameCmsg, FRAME_CMSG_LEN, frame);
239 #else
240     SockSendSetFrameInfo(&msg, frame);
241 #endif
242     msg.msg_flags = 0;
243     return SockSendmsg(sockIndex, &msg, flags);
244 }
245 
SocketMsgGetLen(const struct msghdr * msg)246 static int SocketMsgGetLen(const struct msghdr *msg)
247 {
248     size_t index;
249     FILLP_ULLONG memSize = 0;
250     struct iovec *iov = FILLP_NULL_PTR;
251 
252     if ((msg == FILLP_NULL_PTR) || (msg->msg_iov == FILLP_NULL_PTR)) {
253         FILLP_LOGERR("input msg is null or iov is null");
254         SET_ERRNO(FILLP_EFAULT);
255         return -1;
256     }
257     iov = msg->msg_iov;
258 
259     for (index = 0; index < msg->msg_iovlen; index++) {
260         if (iov[index].iov_base == FILLP_NULL_PTR) {
261             FILLP_LOGERR("input iov_base is null ro iov_len is 0");
262             SET_ERRNO(FILLP_EFAULT);
263             return -1;
264         }
265 
266         memSize = (FILLP_ULLONG)(memSize + (FILLP_ULLONG)(iov[index].iov_len));
267         if ((memSize >= (FILLP_ULLONG)FILLP_MAX_INT_VALUE) || (iov[index].iov_len >= FILLP_MAX_INT_VALUE)) {
268             FILLP_LOGERR("size value big, it need to be less than 2147483647(0x7FFFFFFF)");
269             SET_ERRNO(FILLP_EINVAL);
270             return -1;
271         }
272     }
273 
274     return (int)((FILLP_LLONG)memSize);
275 }
276 
SocketGetForDataTrans(FILLP_INT sockIndex,FILLP_INT flags)277 static struct FtSocket *SocketGetForDataTrans(FILLP_INT sockIndex, FILLP_INT flags)
278 {
279     struct FtSocket *sock = FILLP_NULL_PTR;
280     FillpTraceDescriptSt fillpTrcDesc;
281 
282     sock = SockApiGetAndCheck(sockIndex);
283     if (sock == FILLP_NULL_PTR) {
284         FILLP_LOGERR("sock is null");
285         return FILLP_NULL_PTR;
286     }
287 
288     if (sock->isListenSock == FILLP_TRUE) {
289         (void)SOCK_CONN_UNLOCK_RD(sock);
290         FILLP_LOGERR("netconn is null for sock id=%d", sockIndex);
291         SET_ERRNO(FILLP_ENOTCONN);
292         return FILLP_NULL_PTR;
293     }
294 
295     if (sock->netconn == FILLP_NULL_PTR) {
296         (void)SOCK_CONN_UNLOCK_RD(sock);
297         FILLP_LOGERR("sock not connect");
298         SET_ERRNO(FILLP_ENOTCONN);
299         return FILLP_NULL_PTR;
300     }
301 
302     (void)memset_s(&fillpTrcDesc, sizeof(fillpTrcDesc), 0, sizeof(fillpTrcDesc));
303     fillpTrcDesc.traceDirection = FILLP_TRACE_DIRECT_SEND;
304     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sockIndex,
305         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : sock_send_rcv_param_validate socket:%d flags:%d",
306         sockIndex, flags));
307 
308     return sock;
309 }
310 
311 #ifdef SOCK_SEND_SEM
SockSendReqFpcbItemWithSem(struct FtSocket * sock,FILLP_INT flags)312 static struct FillpPcbItem *SockSendReqFpcbItemWithSem(struct FtSocket *sock, FILLP_INT flags)
313 {
314     FILLP_INT err;
315     struct FillpPcbItem *bufItem = FILLP_NULL_PTR;
316 
317     do {
318         err = SOCK_TRYWAIT_SENDSEM(sock); // Try if can do send
319         if (err != ERR_OK) {
320             if (SOCK_IS_NONBLOCKING(sock) || ((FILLP_UINT32)flags & MSG_DONTWAIT)) {
321                 FILLP_LOGERR("send no buf error");
322                 SET_ERRNO(FILLP_ENOBUFS);
323                 break;
324             }
325             SOCK_SEND_CPU_PAUSE(); // To reduce cpu usage of send api
326             err = SOCK_WAIT_SENDSEM(sock);
327             if (err != ERR_OK) {
328                 FILLP_LOGERR("send busy error");
329                 SET_ERRNO(FILLP_EBUSY);
330                 break;
331             }
332         }
333 
334         if (!SockCanSendData(sock)) {
335             (void)SOCK_POST_SENDSEM(sock); // Need to post here because may other thread is waiting
336             FILLP_LOGERR("Fail to send msg, due to sock is not ready!!!! fillp_sock_id: %d", sock->index);
337             SET_ERRNO(FILLP_ENOTCONN);
338             break;
339         }
340 
341         (void)FillpMallocBufItem(SOCK_GET_SENDPKTPOOL(sock), (void **)&bufItem, FILLP_FALSE);
342     } while (bufItem == FILLP_NULL_PTR);
343 
344     return bufItem;
345 }
346 
347 #else
348 
SockSendReqFpcbItemWithoutSem(struct FtSocket * sock,FILLP_INT flags)349 static struct FillpPcbItem *SockSendReqFpcbItemWithoutSem(struct FtSocket *sock, FILLP_INT flags)
350 {
351     struct FillpPcbItem *bufItem = FILLP_NULL_PTR;
352 
353     do {
354         (void)FillpMallocBufItem(SOCK_GET_SENDPKTPOOL(sock), (void **)&bufItem, FILLP_FALSE);
355         if (bufItem != FILLP_NULL_PTR) {
356             break;
357         }
358 
359         if (!SockCanSendData(sock)) {
360             FILLP_LOGERR("Fail to send msg, due to sock is not ready!!!! fillp_sock_id:%d", sock->index);
361             SET_ERRNO(FILLP_ENOBUFS);
362             break;
363         }
364 
365         if ((SOCK_IS_NONBLOCKING(sock) || ((FILLP_UINT)flags & MSG_DONTWAIT))) {
366             FILLP_LOGERR("Fail to alloc buffer to send,that is not correct!!!! fillp_sock_id:%d", sock->index);
367             SET_ERRNO(FILLP_ENOBUFS);
368             break;
369         }
370         SOCK_SEND_CPU_PAUSE(); // To reduce cpu usage of send api
371     } while (bufItem == FILLP_NULL_PTR);
372 
373     return bufItem;
374 }
375 #endif
376 
SockSendReqFpcbItem(struct FtSocket * sock,FILLP_INT flags)377 static struct FillpPcbItem *SockSendReqFpcbItem(struct FtSocket *sock, FILLP_INT flags)
378 {
379     struct FillpPcbItem *bufItem = FILLP_NULL_PTR;
380 #ifdef SOCK_SEND_SEM
381     bufItem = SockSendReqFpcbItemWithSem(sock, flags);
382 #else /* SOCK_SEND_SEM */
383     bufItem = SockSendReqFpcbItemWithoutSem(sock, flags);
384 #endif /* SOCK_SEND_SEM */
385     if (bufItem != FILLP_NULL_PTR) {
386         (void)SYS_ARCH_ATOMIC_DEC(&sock->sendEventCount, 1);
387     }
388     return bufItem;
389 }
390 
SockSendmsgPushOrSendItem(FILLP_CONST struct FtSocket * sock,struct FillpPcbItem * itemList[],FILLP_UINT32 * itemCnt,struct FillpPcbItem * item)391 static void SockSendmsgPushOrSendItem(FILLP_CONST struct FtSocket *sock,
392     struct FillpPcbItem *itemList[], FILLP_UINT32 *itemCnt, struct FillpPcbItem *item)
393 {
394     if (!FillpPcbGetDirectlySend(&sock->netconn->pcb->fpcb)) {
395         (void)FillpQueuePush(SOCK_GET_SENDBOX(sock), (void *)&item, FILLP_FALSE, 1);
396     } else {
397         FILLP_UINT32 tmpItemCnt = *itemCnt;
398         itemList[tmpItemCnt++] = item;
399         if ((tmpItemCnt == UDP_MAX_SEG) ||
400             (tmpItemCnt >= (FillpPcbGetSendCacheSize(&sock->netconn->pcb->fpcb) >> 1))) { /* > half of the cache */
401             FillpPcbSend(&sock->netconn->pcb->fpcb, itemList, tmpItemCnt);
402             tmpItemCnt = 0;
403         }
404         *itemCnt = tmpItemCnt;
405     }
406 }
407 
SockSendMsgSetItem(struct FillpPcbItem * item,FILLP_CONST struct FtSocket * sock,FILLP_LLONG appSendTime,FILLP_INT sendLen,FILLP_INT bufLen)408 static void SockSendMsgSetItem(struct FillpPcbItem *item, FILLP_CONST struct FtSocket *sock,
409     FILLP_LLONG appSendTime, FILLP_INT sendLen, FILLP_INT bufLen)
410 {
411     FILLP_UINT16 pktDataOptLen = (sock->dataOptionFlag == 0) ? 0 :
412         (FILLP_UINT16)(sock->dataOptionSize + FILLP_DATA_OFFSET_LEN);
413 
414     UTILS_FLAGS_RESET(item->flags);
415     item->netconn = (void *)sock->netconn;
416     item->fpcb = (void *)&sock->netconn->pcb->fpcb;
417     item->dataOptFlag = sock->dataOptionFlag;
418     item->dataOptLen = pktDataOptLen;
419     item->appSendTimestamp = appSendTime;
420     item->appSendSize = (FILLP_UINT32)(bufLen);
421     item->dataLen = (FILLP_UINT16)0;
422     if (sendLen == 0) {
423         UTILS_FLAGS_SET(item->flags, FILLP_ITEM_FLAGS_FIRST_PKT);
424     }
425     if (bufLen >= MAX_APP_DATA_LENGTH_FOR_CAL_COST) {
426         UTILS_FLAGS_SET(item->flags, FILLP_ITEM_FLAGS_APP_LARGE_DATA);
427     }
428     UTILS_FLAGS_SET(item->flags, FILLP_ITEM_FLAGS_REDUNDANT);
429 }
430 
SockItemSetFrameInfo(struct FillpPcbItem * item,FILLP_CONST struct FtSocket * sock,FILLP_CONST struct FrameInfo * frame,struct FillpFrameItem * frameItem,FILLP_INT bufLen)431 static void SockItemSetFrameInfo(struct FillpPcbItem *item, FILLP_CONST struct FtSocket *sock,
432     FILLP_CONST struct FrameInfo *frame, struct FillpFrameItem *frameItem, FILLP_INT bufLen)
433 {
434     FILLP_BOOL isFirstPkt = UTILS_FLAGS_CHECK(item->flags, FILLP_ITEM_FLAGS_FIRST_PKT);
435     FillpFrameItemReference(item, frameItem);
436 
437     if (frameItem == FILLP_NULL_PTR) {
438         return;
439     }
440 
441     FillpFrameTxInitItem(&sock->netconn->pcb->fpcb.frameHandle, item, frame, (FILLP_UINT32)bufLen, isFirstPkt);
442     item->dataOptLen = (FILLP_UINT16)FillpFrameGetPktDataOptLen(item->dataOptFlag, item->dataOptLen);
443 }
444 
SockSendLastItem(FILLP_CONST struct FtSocket * sock,struct FillpPcbItem * item,struct FillpPcbItem * itemList[],FILLP_UINT32 itemCnt)445 static void SockSendLastItem(FILLP_CONST struct FtSocket *sock, struct FillpPcbItem *item,
446     struct FillpPcbItem *itemList[], FILLP_UINT32 itemCnt)
447 {
448     if (item != FILLP_NULL_PTR) {
449         UTILS_FLAGS_SET(item->flags, FILLP_ITEM_FLAGS_LAST_PKT);
450         item->buf.len = (FILLP_INT)(item->dataOptLen + item->dataLen);
451         SockSendmsgPushOrSendItem(sock, itemList, &itemCnt, item);
452     }
453 
454     if (FillpPcbGetDirectlySend(&sock->netconn->pcb->fpcb) && itemCnt > 0) {
455         FillpPcbSend(&sock->netconn->pcb->fpcb, itemList, itemCnt);
456     }
457 }
458 
SockSendmsgDataToBufCache(struct FtSocket * sock,struct msghdr * msg,FILLP_INT flags,FILLP_INT bufLen)459 static FILLP_INT SockSendmsgDataToBufCache(struct FtSocket *sock,
460     struct msghdr *msg, FILLP_INT flags, FILLP_INT bufLen)
461 {
462     FILLP_INT sendLen = 0;
463     FILLP_UINT32 itemRemainLen = 0;
464     FILLP_UINT32 iovRemainLen = 0;
465     FILLP_UINT32 index = 0;
466     FILLP_UINT32 copyLen;
467     FILLP_UINT32 pktSize = (FILLP_UINT32)SOCK_GET_PKTSIZE(sock);
468     char *iovIter = FILLP_NULL_PTR;
469     char *itemIter = FILLP_NULL_PTR;
470     struct FillpPcbItem *item = FILLP_NULL_PTR;
471     struct FillpPcbItem *itemList[UDP_MAX_SEG] = {FILLP_NULL_PTR};
472     FILLP_UINT32 itemCnt = 0;
473     FILLP_LLONG appSendTime = SYS_ARCH_GET_CUR_TIME_LONGLONG();
474     FILLP_CONST struct FrameInfo *frame = SockSendGetFrameInfo(msg);
475     struct FillpFrameItem *frameItem = FillpFrameItemAlloc(frame);
476 
477     while (sendLen != bufLen) {
478         SOCK_SENDMSG_DATA_MOD_IOV(iovRemainLen, iovIter, msg, index);
479 
480         if (itemRemainLen == 0) {
481             if (item != FILLP_NULL_PTR) {
482                 item->buf.len = (FILLP_INT)(item->dataOptLen + item->dataLen);
483                 SockSendmsgPushOrSendItem(sock, itemList, &itemCnt, item);
484             }
485             item = SockSendReqFpcbItem(sock, flags);
486             if (item == FILLP_NULL_PTR) {
487                 break;
488             }
489 
490             SockSendMsgSetItem(item, sock, appSendTime, sendLen, bufLen);
491             SockItemSetFrameInfo(item, sock, frame, frameItem, bufLen);
492             itemIter = item->buf.p + FILLP_HLEN + item->dataOptLen;
493             itemRemainLen = pktSize - item->dataOptLen;
494         }
495 
496         if (item == FILLP_NULL_PTR || iovIter == FILLP_NULL_PTR || itemIter == FILLP_NULL_PTR) {
497             FILLP_LOGERR("item or iovIter NULL");
498             return -1;
499         }
500         copyLen = (itemRemainLen > iovRemainLen) ? iovRemainLen : itemRemainLen;
501         if (memcpy_s(itemIter, itemRemainLen, iovIter, copyLen) != EOK) {
502             FILLP_LOGERR("SockSendmsgDataToBufCache: memcpy failed");
503             return -1;
504         }
505 
506         SOCK_SENDMSG_DATA_MOD_LEN(iovIter, iovRemainLen, itemIter, itemRemainLen, sendLen, item->dataLen, copyLen);
507     }
508 
509     SockSendLastItem(sock, item, itemList, itemCnt);
510     SpungeEpollEventCallback(sock, SPUNGE_EPOLLOUT, 1);
511 
512     FillpFrameItemPut(frameItem);
513     return sendLen;
514 }
515 
SockSendmsg(FILLP_INT sockIndex,struct msghdr * msg,FILLP_INT flags)516 FILLP_INT SockSendmsg(FILLP_INT sockIndex, struct msghdr *msg, FILLP_INT flags)
517 {
518     FILLP_INT sendLen;
519     struct FtSocket *sock = FILLP_NULL_PTR;
520 
521     sendLen = SocketMsgGetLen(msg);
522     if (sendLen <= 0) {
523         return sendLen;
524     }
525 
526     sock = SocketGetForDataTrans(sockIndex, flags);
527     if (sock == FILLP_NULL_PTR) {
528         return -1;
529     }
530 
531     if (SockCanSendData(sock) == FILLP_FALSE) {
532         (void)SOCK_CONN_UNLOCK_RD(sock);
533         FILLP_SOCK_SET_ERR(sock, FILLP_ENOTCONN);
534         FILLP_LOGERR("send not conncet error");
535         SET_ERRNO(FILLP_ENOTCONN);
536         return -1;
537     }
538 
539     sendLen = SockSendmsgDataToBufCache(sock, msg, flags, sendLen);
540     (void)SOCK_CONN_UNLOCK_RD(sock);
541     if (sendLen > 0) {
542         FILLP_SOCK_SET_ERR(sock, ERR_OK);
543         return sendLen;
544     }
545 
546     if (SockCanSendData(sock)) {
547         FILLP_SOCK_SET_ERR(sock, FILLP_EAGAIN);
548         FILLP_LOGERR("send again error");
549         SET_ERRNO(FILLP_EAGAIN);
550     } else {
551         FILLP_SOCK_SET_ERR(sock, FILLP_ECONNRESET);
552         FILLP_LOGERR("send connect reset error");
553         SET_ERRNO(FILLP_ECONNRESET);
554     }
555     return -1;
556 }
557 
SockRecv(FILLP_INT s,void * mem,FILLP_SIZE_T len,FILLP_INT flags)558 FILLP_INT SockRecv(FILLP_INT s, void *mem, FILLP_SIZE_T len, FILLP_INT flags)
559 {
560     struct iovec msgIov;
561     struct msghdr msg;
562 
563     if ((mem == FILLP_NULL_PTR) || (len == 0)) {
564         FILLP_LOGERR("input data is pointer is null for sock id, fillp_sock_id:%d", s);
565         SET_ERRNO(FILLP_EINVAL);
566         return -1;
567     }
568 
569     msgIov.iov_base = mem;
570     msgIov.iov_len = len;
571 
572     msg.msg_name = FILLP_NULL_PTR;
573     msg.msg_namelen = 0;
574     msg.msg_iov = &msgIov;
575     msg.msg_iovlen = 1;
576     msg.msg_control = FILLP_NULL_PTR;
577     msg.msg_controllen = 0;
578     msg.msg_flags = 0;
579     return SockRecvmsg(s, &msg, flags);
580 }
581 
582 #ifdef SOCK_RECV_SEM
SockRecvReqFpcbItemWithSem(struct FtSocket * sock,FILLP_INT flags)583 static struct FillpPcbItem *SockRecvReqFpcbItemWithSem(struct FtSocket *sock, FILLP_INT flags)
584 {
585     FILLP_INT err;
586     struct FillpPcbItem *bufItem = FILLP_NULL_PTR;
587 
588     do {
589         err = SOCK_TRYWAIT_RECVSEM(sock); // Try if can do recv
590         if (err != ERR_OK) {
591             if (SOCK_IS_NONBLOCKING(sock) || ((FILLP_UINT)flags & MSG_DONTWAIT)) {
592                 break;
593             }
594             SOCK_SEND_CPU_PAUSE(); // To reduce cpu usage of send api
595             err = SOCK_WAIT_RECVSEM(sock);
596             if (err != ERR_OK) {
597                 break;
598             }
599         }
600 
601         (void)FillpQueuePop(SOCK_GET_RECVBOX(sock), (void **)&bufItem, 1);
602         if ((bufItem == FILLP_NULL_PTR) && (!SockCanRecvData(sock))) {
603             (void)SOCK_POST_RECVSEM(sock); // Need to post here because may other thread is waiting
604             FILLP_LOGERR("Fail to send msg, due to sock is not ready!!!! fillp_sock_id:%d", sock->index);
605             break;
606         }
607     } while (bufItem == FILLP_NULL_PTR);
608 
609     return bufItem;
610 }
611 
612 #else
613 
SockRecvReqFpcbItemWithoutSem(struct FtSocket * sock,FILLP_INT flags)614 static struct FillpPcbItem *SockRecvReqFpcbItemWithoutSem(struct FtSocket *sock, FILLP_INT flags)
615 {
616     struct FillpPcbItem *bufItem = FILLP_NULL_PTR;
617 
618     do {
619         (void)FillpQueuePop(SOCK_GET_RECVBOX(sock), (void **)&bufItem, 1);
620         if (bufItem != FILLP_NULL_PTR) {
621             break;
622         }
623 
624         if (!SockCanRecvData(sock)) {
625             FILLP_LOGERR("Fail to recv msg, due to sock is not ready!!!! fillp_sock_id:%d", sock->index);
626             break;
627         }
628 
629         if ((SOCK_IS_NONBLOCKING(sock) || ((FILLP_UINT32)flags & MSG_DONTWAIT))) {
630             FILLP_LOGDBG("fillp_sock_id:%d, Fail to get data buffer to recv", sock->index);
631             break;
632         }
633         SOCK_RECV_CPU_PAUSE(); // To reduce cpu usage of send api
634     } while (bufItem == FILLP_NULL_PTR);
635 
636     return bufItem;
637 }
638 #endif
639 
SockRecvReqFpcbItem(struct FtSocket * sock,FILLP_INT flags)640 static struct FillpPcbItem *SockRecvReqFpcbItem(struct FtSocket *sock, FILLP_INT flags)
641 {
642     struct FillpPcbItem *bufItem = FILLP_NULL_PTR;
643 
644     if (sock->recvPktBuf != FILLP_NULL_PTR) {
645         bufItem = (struct FillpPcbItem *)sock->recvPktBuf;
646         if (bufItem->dataLen == 0) {
647             FillpFreeBufItem(sock->recvPktBuf);
648             sock->recvPktBuf = FILLP_NULL;
649             sock->offset = 0;
650             SpungeEpollAppRecvOne(sock);
651         } else {
652             return bufItem;
653         }
654     }
655 
656 #ifdef SOCK_RECV_SEM
657     bufItem = SockRecvReqFpcbItemWithSem(sock, flags);
658 #else /* SOCK_RECV_SEM */
659     bufItem = SockRecvReqFpcbItemWithoutSem(sock, flags);
660 #endif /* SOCK_RECV_SEM */
661     if (bufItem != FILLP_NULL_PTR) {
662         sock->recvPktBuf = (void *)bufItem;
663         sock->offset = bufItem->dataOptLen;
664     }
665 
666     return bufItem;
667 }
668 
SockRecvmsgDataFromBufCache(struct FtSocket * sock,struct msghdr * msg,FILLP_INT flags,FILLP_INT bufLen)669 static FILLP_INT SockRecvmsgDataFromBufCache(struct FtSocket *sock,
670     struct msghdr *msg, FILLP_INT flags, FILLP_INT bufLen)
671 {
672     struct FillpPcbItem *item = FILLP_NULL_PTR;
673     FILLP_INT rcvLen = 0;
674     FILLP_INT ret;
675     FILLP_UINT32 itemRemainLen = 0;
676     FILLP_UINT32 iovRemainLen = 0;
677     FILLP_UINT32 index = 0;
678     FILLP_UINT32 copyLen;
679     char *iovIter = FILLP_NULL_PTR;
680     char *itemIter = FILLP_NULL_PTR;
681 
682     while (rcvLen != bufLen) {
683         SOCK_SENDMSG_DATA_MOD_IOV(iovRemainLen, iovIter, msg, index);
684 
685         if (itemRemainLen == 0) {
686             /* SOCK_DGRAM mode, at most 1 pkt will be returned */
687             if ((sock->socketType == SOCK_DGRAM) && (item != FILLP_NULL_PTR)) {
688                 break;
689             }
690             if (rcvLen > 0) {
691                 flags = (FILLP_INT)((FILLP_UINT)flags | MSG_DONTWAIT);
692             }
693             item = SockRecvReqFpcbItem(sock, flags);
694             if (item == FILLP_NULL_PTR) {
695                 break;
696             }
697             itemIter = item->buf.p + FILLP_HLEN + sock->offset;
698             itemRemainLen = item->dataLen;
699         }
700 
701         if (item == FILLP_NULL_PTR || iovIter == FILLP_NULL_PTR || itemIter == FILLP_NULL_PTR) {
702             FILLP_LOGERR("item or iovIter NULL");
703             return -1;
704         }
705 
706         copyLen = (itemRemainLen > iovRemainLen) ? iovRemainLen : itemRemainLen;
707         ret = memcpy_s(iovIter, iovRemainLen, itemIter, copyLen);
708         if (ret != EOK) {
709             FILLP_LOGERR("SockRecvmsgDataFromBufCache: memcpy fail, err code:%d", ret);
710             return -1;
711         }
712 
713         SOCK_SENDMSG_DATA_MOD_LEN(iovIter, iovRemainLen, itemIter, itemRemainLen, rcvLen, sock->offset, copyLen);
714         item->dataLen -= (FILLP_UINT16)copyLen;
715     }
716 
717     if ((item != FILLP_NULL_PTR) &&
718         ((item->dataLen == 0) || ((iovRemainLen == 0) && (sock->socketType == SOCK_DGRAM)))) {
719         FillpFreeBufItem(sock->recvPktBuf);
720         sock->recvPktBuf = FILLP_NULL;
721         sock->offset = 0;
722         SpungeEpollAppRecvOne(sock);
723     }
724 
725     return rcvLen;
726 }
727 
SockRecvmsg(FILLP_INT sockIndex,struct msghdr * msg,FILLP_INT flags)728 FILLP_INT SockRecvmsg(FILLP_INT sockIndex, struct msghdr *msg, FILLP_INT flags)
729 {
730     FILLP_INT recvLen;
731     struct FtSocket *sock = FILLP_NULL_PTR;
732     FILLP_INT ret;
733 
734     recvLen = SocketMsgGetLen(msg);
735     if (recvLen <= 0) {
736         FILLP_LOGERR("get msglen fail");
737         return -1;
738     }
739 
740     sock = SocketGetForDataTrans(sockIndex, flags);
741     if (sock == FILLP_NULL_PTR) {
742         FILLP_LOGERR("sock is null");
743         return -1;
744     }
745 
746     if ((sock->netconn->state != CONN_STATE_CONNECTED) && (sock->netconn->state != CONN_STATE_CLOSING) &&
747         (sock->netconn->state != CONN_STATE_CLOSED)) {
748         (void)SOCK_CONN_UNLOCK_RD(sock);
749         FILLP_LOGERR("sock not connect");
750         SET_ERRNO(FILLP_ENOTCONN);
751         return -1;
752     }
753 
754     if (msg->msg_name != FILLP_NULL_PTR) {
755         ret = memcpy_s(msg->msg_name, msg->msg_namelen, &sock->netconn->pcb->remoteAddr, sock->netconn->pcb->addrLen);
756         if (ret != EOK) {
757             FILLP_LOGERR("SockRecvmsg: memcpy fail, err code:%d", ret);
758             return -1;
759         }
760         msg->msg_namelen = sock->netconn->pcb->addrLen;
761     }
762 
763     recvLen = SockRecvmsgDataFromBufCache(sock, msg, flags, recvLen);
764     (void)SOCK_CONN_UNLOCK_RD(sock);
765     if (recvLen > 0) {
766         FILLP_SOCK_SET_ERR(sock, ERR_OK);
767         return recvLen;
768     }
769 
770     if (SockCanRecvData(sock)) {
771         FILLP_SOCK_SET_ERR(sock, FILLP_EAGAIN);
772         FILLP_LOGERR("recv again error");
773         SET_ERRNO(FILLP_EAGAIN);
774         return -1;
775     }
776 
777     FILLP_SOCK_SET_ERR(sock, FILLP_ECONNRESET);
778     FILLP_LOGERR("recv connect reset error");
779     SET_ERRNO(FILLP_ECONNRESET);
780     return 0;
781 }
782 
SockWritev(FILLP_INT sockIndex,const struct iovec * iov,FILLP_INT iovCount)783 FillpErrorType SockWritev(FILLP_INT sockIndex, const struct iovec *iov, FILLP_INT iovCount)
784 {
785     struct msghdr msg;
786 
787     if (iov == FILLP_NULL_PTR) {
788         FILLP_LOGERR("input iov is pointer is null for sock id fillp_sock_id:%d", sockIndex);
789         SET_ERRNO(FILLP_EFAULT);
790         return -1;
791     }
792 
793     if (iovCount == 0) {
794         return 0;
795     }
796 
797     (void)memset_s(&msg, sizeof(struct msghdr), 0, sizeof(struct msghdr));
798     msg.msg_iov = (struct iovec *)iov;
799     msg.msg_iovlen = (size_t)(FILLP_UINT)iovCount;
800 
801     return SockSendmsg(sockIndex, &msg, 0);
802 }
803 
SockReadv(FILLP_INT sockIndex,const struct iovec * iov,FILLP_INT iovCount)804 FillpErrorType SockReadv(FILLP_INT sockIndex, const struct iovec *iov, FILLP_INT iovCount)
805 {
806     struct msghdr msg;
807 
808     if (iov == FILLP_NULL_PTR) {
809         FILLP_LOGERR("input iov is pointer is null for sock id fillp_sock_id:%d", sockIndex);
810         SET_ERRNO(FILLP_EFAULT);
811         return -1;
812     }
813 
814     if (iovCount == 0) {
815         return 0;
816     }
817 
818     (void)memset_s(&msg, sizeof(struct msghdr), 0, sizeof(struct msghdr));
819     msg.msg_iov = (struct iovec *)iov;
820     msg.msg_iovlen = (size_t)(FILLP_UINT)iovCount;
821 
822     return SockRecvmsg(sockIndex, &msg, 0);
823 }
824 
SockApiGetAndCheckListenState(FILLP_INT sockIndex,FILLP_INT backLog,FillpErrorType * err)825 static struct FtSocket *SockApiGetAndCheckListenState(FILLP_INT sockIndex, FILLP_INT backLog, FillpErrorType *err)
826 {
827     struct FtSocket *sock = FILLP_NULL_PTR;
828 
829     *err = -1;
830     if (backLog < 0) {
831         FILLP_LOGERR("Backlog is invalid fillp_sock_id:%d,backLog:%d", sockIndex, backLog);
832         SET_ERRNO(FILLP_EINVAL);
833         return FILLP_NULL_PTR;
834     }
835 
836     /* errno is set inside the function upon failure */
837     sock = SockApiGetAndCheck(sockIndex);
838     if (sock == FILLP_NULL_PTR) {
839         return FILLP_NULL_PTR;
840     }
841 
842     if (sock->isSockBind == FILLP_FALSE) {
843         FILLP_LOGERR("socket Id %d not bind ip", sockIndex);
844         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
845         SET_ERRNO(FILLP_EINVAL);
846         return FILLP_NULL_PTR;
847     }
848 
849     /* Call listen on the same socket fd twice: Kernel behavior: return success */
850     if (sock->isListenSock == FILLP_TRUE) {
851         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
852         *err = 0;
853         return FILLP_NULL_PTR;
854     }
855 
856     if (sock->netconn == FILLP_NULL_PTR) {
857         FILLP_LOGERR("sock->netconn is NULL, fillp_sock_id:%d", sockIndex);
858         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
859         SET_ERRNO(FILLP_ENOTCONN);
860         return FILLP_NULL_PTR;
861     }
862 
863     return sock;
864 }
865 
SockListen(FILLP_INT sockIndex,FILLP_INT backLog)866 FillpErrorType SockListen(FILLP_INT sockIndex, FILLP_INT backLog)
867 {
868     struct FtSocket *sock = FILLP_NULL_PTR;
869     FillpErrorType err;
870     FillpTraceDescriptSt fillpTrcDesc = FILLP_TRACE_DESC_INIT(FILLP_TRACE_DIRECT_SEND);
871 
872     FILLP_LOGINF("SockListen, fillp_sock_id:%d, backLog:%d", sockIndex, backLog);
873 
874     sock = SockApiGetAndCheckListenState(sockIndex, backLog, &err);
875     if (sock == FILLP_NULL_PTR) {
876         return err;
877     }
878 
879     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sockIndex,
880         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : FtListen->SockListen socket:%d backlog:%d \r\n",
881         sockIndex, backLog));
882 
883     if ((backLog == 0) || (backLog > (FILLP_INT)g_spunge->resConf.maxConnNum)) {
884         FILLP_LOGWAR("input backLog is not equal to configured value"
885             " so using the configured value backLog:%d, configValue:%u,fillp_sock_id:%d",
886             backLog, g_spunge->resConf.maxConnNum, sock->index);
887 
888         backLog = (FILLP_INT)g_spunge->resConf.maxConnNum;
889     }
890 
891     sock->listenBacklog = backLog;
892 
893     err = SpungePostMsg(sock->inst, sock, MSG_TYPE_DO_LISTEN, FILLP_TRUE);
894     if (err != ERR_OK) {
895         FILLP_LOGERR("failed to post msg to fillp sock->index = %d\r\n", sock->index);
896 
897         sock->listenBacklog = 0;
898         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
899         SET_ERRNO(FILLP_ENOBUFS);
900         return -1;
901     }
902 
903     err = sock->coreErrType[MSG_TYPE_DO_LISTEN];
904     FillpNetconnSetSafeErr(sock->netconn, err);
905     if (err != ERR_OK) {
906         SockSetError(sock, err);
907         err = -1;
908     }
909 
910     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
911     return err;
912 }
913 
SockAcceptGetAndCheck(FILLP_INT sockFd)914 static struct FtSocket *SockAcceptGetAndCheck(FILLP_INT sockFd)
915 {
916     struct FtSocket *sock = SockApiGetAndCheck(sockFd);
917     if (sock == FILLP_NULL_PTR) {
918         return FILLP_NULL_PTR;
919     }
920 
921     if (sock->netconn == FILLP_NULL_PTR) {
922         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
923 
924         FILLP_LOGERR("network connection doesnot exist to accept : sockFd=%d", sockFd);
925         SET_ERRNO(FILLP_ENOTCONN);
926         return FILLP_NULL_PTR;
927     }
928 
929     if (sock->isListenSock == FILLP_FALSE) {
930         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
931 
932         FILLP_LOGERR("connection state is not in listening mode for sockFd=%d", sockFd);
933         SET_ERRNO(FILLP_EINVAL);
934         return FILLP_NULL_PTR;
935     }
936 
937     if (sock->acceptBox == FILLP_NULL_PTR) {
938         FILLP_LOGERR("accept box is NULL fillp_sock_id:%d", sockFd);
939         SET_ERRNO(FILLP_EINVAL);
940         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
941         return FILLP_NULL_PTR;
942     }
943 
944     return sock;
945 }
946 
SockCopyAddr(struct sockaddr * addr,socklen_t * addrLen,struct FtNetconn * conn)947 static void SockCopyAddr(struct sockaddr *addr, socklen_t *addrLen, struct FtNetconn *conn)
948 {
949     FILLP_INT ret;
950 
951     if ((addr != FILLP_NULL_PTR) && (addrLen != FILLP_NULL_PTR)) {
952         socklen_t localAddrLen = sizeof(struct sockaddr);
953         if (((struct sockaddr_in *)((void *)&(conn->pcb->remoteAddr)))->sin_family == AF_INET6) {
954             localAddrLen = sizeof(struct sockaddr_in6);
955         }
956 
957         if (*addrLen >= localAddrLen) {
958             *addrLen = localAddrLen;
959         }
960 
961         if (*addrLen > 0) {
962             ret = memcpy_s(addr, *addrLen, &conn->pcb->remoteAddr, *addrLen);
963             if (ret != EOK) {
964                 FILLP_LOGERR("memcpy_s failed with errcode %d", ret);
965                 return;
966             }
967         }
968     }
969 }
970 
SockPopConn(struct FtSocket * sock,FILLP_INT sockFd)971 static struct FtNetconn *SockPopConn(struct FtSocket *sock, FILLP_INT sockFd)
972 {
973     struct FtNetconn *conn = FILLP_NULL_PTR;
974     FILLP_INT ret;
975 
976     /* Making the FtAccept call non blocking
977        TCP accept():
978        a) The accept() function shall extract the first connection on
979        the queue of pending connections, create a new socket with the same socket
980        type protocol and address family as the specified socket, and allocate a
981        new file descriptor for that socket.
982 
983        b) If the listen queue is empty of connection requests and O_NONBLOCK is not
984        set on the file descriptor for the socket, accept() shall block until a
985        connection is present. If the listen() queue is empty of connection requests
986        and O_NONBLOCK is set on the file descriptor for the socket, accept() shall
987        fail and set errno to [EAGAIN] or [EWOULDBLOCK].
988 
989        c) The accept() function shall fail if:
990        [EAGAIN] or [EWOULDBLOCK]
991        O_NONBLOCK is set for the socket file descriptor and no connections are present to be accepted.
992     */
993     ret = FillpQueuePop(sock->acceptBox, (void *)&conn, 1);
994     if (ret <= 0) {
995         if ((SOCK_IS_NONBLOCKING(sock))) {
996             (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
997 
998             FILLP_LOGINF("SockAccept: connection request not received for listenID  = %d \r\n", sockFd);
999             FILLP_SOCK_SET_ERR(sock, FILLP_EINPROGRESS);
1000             SET_ERRNO(FILLP_EAGAIN);
1001             /* Returns less than 0 value */
1002             return FILLP_NULL_PTR;
1003         } else {
1004             if (SYS_ARCH_SEM_WAIT(&sock->acceptSem)) {
1005                 (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1006 
1007                 FILLP_LOGERR("Error wait acceptSem, sockFd = %d \r\n", sockFd);
1008                 FILLP_SOCK_SET_ERR(sock, FILLP_ENOMEM);
1009                 SET_ERRNO(FILLP_ENOMEM);
1010                 /* Returns less than 0 value */
1011                 return FILLP_NULL_PTR;
1012             }
1013 
1014             ret = FillpQueuePop(sock->acceptBox, (void *)&conn, 1);
1015             if (ret <= 0) {
1016                 (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1017 
1018                 FILLP_LOGERR("SockAccept: pop error for sock Id = %d \r\n", sockFd);
1019                 SET_ERRNO(FILLP_ENODATA);
1020                 return FILLP_NULL_PTR;
1021             }
1022         }
1023     } else {
1024         if (!SOCK_IS_NONBLOCKING(sock) && (SYS_ARCH_SEM_WAIT(&sock->acceptSem))) {
1025             (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1026 
1027             FILLP_LOGERR("sem wait is failing when there is connection to be accepted, "
1028                          " Abnormal stack behavior, Server sockFd = %d \r\n", sockFd);
1029             FILLP_SOCK_SET_ERR(sock, FILLP_ENOMEM);
1030             SET_ERRNO(FILLP_ENOMEM);
1031             /* Returns less than 0 value */
1032             return FILLP_NULL_PTR;
1033         }
1034     }
1035 
1036     return conn;
1037 }
1038 
SockAccept(FILLP_INT sockFd,struct sockaddr * addr,socklen_t * addrLen)1039 FillpErrorType SockAccept(FILLP_INT sockFd, struct sockaddr *addr, socklen_t *addrLen)
1040 {
1041     FillpErrorType err;
1042     struct FtSocket *sock = SockAcceptGetAndCheck(sockFd);
1043     struct FtNetconn *conn = FILLP_NULL_PTR;
1044     FillpTraceDescriptSt fillpTrcDesc;
1045     struct SpungeAcceptMsg acceptMsg;
1046 
1047     FILLP_LOGINF("sock_accpet:%d", sockFd);
1048 
1049     if (sock == FILLP_NULL_PTR) {
1050         return -1;
1051     }
1052 
1053     fillpTrcDesc.traceDirection = FILLP_TRACE_DIRECT_SEND;
1054     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sockFd,
1055         (FILLP_UINT8 *)(void *)&fillpTrcDesc,
1056         "Entering Function : FtAccept->SockAccept socket:%d\r\n", sockFd));
1057 
1058     /* do SYS_ARCH_RWSEM_RDPOST in SockPopConn */
1059     conn = SockPopConn(sock, sockFd);
1060     if (conn == FILLP_NULL_PTR) {
1061         return -1;
1062     }
1063 
1064     SpungeEpollAppRecvOne(sock);
1065 
1066     acceptMsg.listenSock = (void *)sock;
1067     acceptMsg.netconn = conn;
1068 
1069     err = SpungePostMsg(sock->inst, (void *)&acceptMsg, MSG_TYPE_NETCONN_ACCPETED, FILLP_TRUE);
1070     if (err != ERR_OK) {
1071         FILLP_LOGERR("Failed to post msg to core, fillp_sock_id:%d", sock->index);
1072         SOCK_DESTROY_CONN(&sock->sockConnSem, conn, sock, FILLP_ENOBUFS);
1073         return -1;
1074     }
1075 
1076     if (sock->coreErrType[MSG_TYPE_NETCONN_ACCPETED] != ERR_OK) {
1077         FILLP_LOGERR("Failed in core to accept socket Id for listen fillp_sock_id:%d", sockFd);
1078         SOCK_DESTROY_CONN(&sock->sockConnSem, conn, sock, FILLP_ENOMEM);
1079         return -1;
1080     }
1081 
1082     SockCopyAddr(addr, addrLen, conn);
1083 
1084     FILLP_SOCK_SET_ERR(sock, ERR_OK);
1085     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1086 
1087     FILLP_LOGINF("sock_accpet return.listen fillp_sock_id:%d, accepted:%d", sockFd,
1088                  ((struct FtSocket *)conn->sock)->index);
1089     return ((struct FtSocket *)conn->sock)->index;
1090 }
1091 
SockClose(FILLP_INT sockIndex)1092 FillpErrorType SockClose(FILLP_INT sockIndex)
1093 {
1094     struct FtSocket *sock = SockGetSocket(sockIndex);
1095     FILLP_INT err;
1096     FillpTraceDescriptSt fillpTrcDesc = FILLP_TRACE_DESC_INIT(FILLP_TRACE_DIRECT_SEND);
1097 
1098     if (sock == FILLP_NULL_PTR) {
1099         FILLP_LOGERR("Invalid fillp_sock_id:%d", sockIndex);
1100         SET_ERRNO(FILLP_EBADF);
1101         return -1;
1102     }
1103 
1104     FILLP_LOGINF("fillp_sock_id:%d, state:%d, linger:%d", sockIndex, sock->allocState, sock->fillpLinger.l_onoff);
1105 
1106     if (SOCK_CONN_TRY_RDLOCK(sock) != ERR_OK) {
1107         FILLP_LOGERR("Socket-%d is closing", sockIndex);
1108         SET_ERRNO(FILLP_EBUSY);
1109         return -1;
1110     }
1111 
1112     if ((sock->allocState != SOCK_ALLOC_STATE_COMM) && (sock->allocState != SOCK_ALLOC_STATE_EPOLL)) {
1113         (void)SOCK_CONN_UNLOCK_RD(sock);
1114 
1115         FILLP_LOGERR("socket state is incorrect for fillp_sock_id:%d,state=%d", sockIndex, sock->allocState);
1116 
1117         SET_ERRNO(FILLP_ENOTSOCK);
1118         return -1;
1119     }
1120 
1121     /* Just lock, no need to unlock, it is used for dumplicate close
1122        Dumplicate close may push two close message to fillp stack, if the first one has
1123        released the resource, then the second one will make bugs */
1124     if (SOCK_CONN_TRY_LOCK_CLOSE(sock) != ERR_OK) {
1125         FILLP_LOGERR("Try to lock close fail, maybe close already called before, fillp_sock_id:%d", sockIndex);
1126         SET_ERRNO(FILLP_EINVAL);
1127         (void)SOCK_CONN_UNLOCK_RD(sock);
1128         return -1;
1129     }
1130 
1131     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sockIndex,
1132         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : FtClose->SockClose Socket:%d \r\n", sockIndex));
1133 
1134     /* Before waiting for the core to complete the task, we must release the
1135            socket lock as core might require same.
1136     */
1137     (void)SOCK_CONN_UNLOCK_RD(sock);
1138 
1139     if (sock->fillpLinger.l_onoff) {
1140         sock->lingering = FILLP_TRUE;
1141     } else {
1142         sock->lingering = FILLP_FALSE;
1143     }
1144 
1145     err = SpungePostMsg(sock->inst, sock, MSG_TYPE_DO_CLOSE, FILLP_TRUE);
1146     if (err != ERR_OK) {
1147         FILLP_LOGERR("Failed to Close the Socket. SpungePostMsg returns failure. fillp_sock_id:%d \r\n", sockIndex);
1148         /* nothing can be done for post failure */
1149         (void)SOCK_CONN_UNLOCK_CLOSE(sock);
1150         SET_ERRNO(FILLP_ENOBUFS);
1151         return -1;
1152     }
1153 
1154     err = sock->coreErrType[MSG_TYPE_DO_CLOSE];
1155 
1156     FILLP_LOGINF("return fillp_sock_id:%d,err:%d,state:%d", sockIndex, err, sock->allocState);
1157     if (err != ERR_OK) {
1158         /* handle close can fail for semaphore wait epollTaskListLock,
1159            but application do not care about failure of FtClose, so this socket anyways hangs */
1160         err = -1;
1161     }
1162 
1163     return err;
1164 }
1165 
SockCheckCanShutdown(struct FtSocket * sock,FILLP_INT sockIndex)1166 static FILLP_INT SockCheckCanShutdown(struct FtSocket *sock, FILLP_INT sockIndex)
1167 {
1168     if ((sock->netconn == FILLP_NULL_PTR) || (NETCONN_GET_STATE(sock->netconn) != CONN_STATE_CONNECTED)) {
1169         /* For listen socket shutdown always return success */
1170         if ((sock->netconn != FILLP_NULL_PTR) && (CONN_STATE_LISTENING == NETCONN_GET_STATE(sock->netconn))) {
1171             (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1172             return FILLP_ERR_ISCONN;
1173         }
1174 
1175         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1176         FILLP_LOGERR("SockShutdown: netconn state is not CONNECTED for socket Id  = %d", sockIndex);
1177         SET_ERRNO(FILLP_ENOTCONN);
1178         return -1;
1179     }
1180 
1181     return ERR_OK;
1182 }
1183 
SockShutdown(FILLP_INT sockIndex,FILLP_INT how)1184 FillpErrorType SockShutdown(FILLP_INT sockIndex, FILLP_INT how)
1185 {
1186     struct FtSocket *sock = SockApiGetAndCheck(sockIndex);
1187     FillpTraceDescriptSt fillpTrcDesc = FILLP_TRACE_DESC_INIT(FILLP_TRACE_DIRECT_SEND);
1188     FILLP_INT err;
1189     struct SpungeShutdownMsg shutdownMsg;
1190 
1191     FILLP_LOGINF("fillp_sock_id:%d", sockIndex);
1192 
1193     if (sock == FILLP_NULL_PTR) {
1194         return -1;
1195     }
1196 
1197     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sockIndex,
1198         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : FtShutDown->SockShutdown Socket:%d \r\n",
1199         sockIndex));
1200 
1201     err = SockCheckCanShutdown(sock, sockIndex);
1202     if (err == FILLP_ERR_ISCONN) {
1203         return ERR_OK;
1204     } else if (err != ERR_OK) {
1205         return -1;
1206     }
1207 
1208     if ((how != SPUNGE_SHUT_RD) && (how != SPUNGE_SHUT_RDWR) && (how != SPUNGE_SHUT_WR)) {
1209         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1210         SET_ERRNO(FILLP_EINVAL);
1211         FILLP_LOGERR("how value is not support, fillp_sock_id: %d, how: %d", sockIndex, how);
1212         return -1;
1213     }
1214 
1215     shutdownMsg.how = how;
1216     shutdownMsg.sock = sock;
1217 
1218     sock->lingering = FILLP_FALSE;
1219     err = SpungePostMsg(sock->inst, (void *)&shutdownMsg, MSG_TYPE_DO_SHUTDOWN, FILLP_TRUE);
1220     if (err != ERR_OK) {
1221         FILLP_LOGERR("Failed to Shutdown the Socket. SpungePostMsg returns failure. fillp_sock_id:%d \r\n", sockIndex);
1222         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1223         SET_ERRNO(FILLP_ENOBUFS);
1224         return -1;
1225     }
1226 
1227     err = sock->coreErrType[MSG_TYPE_DO_SHUTDOWN];
1228     FillpNetconnSetSafeErr(sock->netconn, err);
1229     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1230 
1231     FILLP_LOGINF("shut down finished, fillp_sock_id:%d,err:%d", sockIndex, err);
1232     if (err != ERR_OK) {
1233         err = -1;
1234     }
1235 
1236     return err;
1237 }
1238 
SockBindConnectValidateParams(struct FtSocket * sock,FILLP_CONST struct sockaddr * name,FILLP_UINT32 nameLen)1239 static FillpErrorType SockBindConnectValidateParams(struct FtSocket *sock,
1240     FILLP_CONST struct sockaddr *name,  FILLP_UINT32 nameLen)
1241 {
1242     FillpTraceDescriptSt fillpTrcDesc = FILLP_TRACE_DESC_INIT(FILLP_TRACE_DIRECT_SEND);
1243 
1244     if (name  == FILLP_NULL_PTR) {
1245         FILLP_LOGERR("Input address is not correct, fillp_sock_id:%d", sock->index);
1246         SET_ERRNO(FILLP_EFAULT);
1247         return ERR_NULLPTR;
1248     }
1249 
1250     if (sock->sockAddrType != name->sa_family) {
1251         FILLP_LOGERR("addrType not match, fillp_sock_id:%d,sock->addrType:%u,name->addrType:%u", sock->index,
1252             sock->sockAddrType, name->sa_family);
1253 
1254         SET_ERRNO(FILLP_EAFNOSUPPORT);
1255         return ERR_SOCK_TYPE_ERR;
1256     }
1257 
1258     if (sock->sockAddrType == AF_INET) {
1259         struct sockaddr_in *ipv4Addr = (struct sockaddr_in *)name;
1260         if (nameLen < sizeof(struct sockaddr_in)) {
1261             FILLP_LOGERR("nameLen is too less for ipv4 addr, nameLen:%u", nameLen);
1262             SET_ERRNO(FILLP_EINVAL);
1263             return ERR_SOCK_TYPE_ERR;
1264         }
1265 
1266         if (ipv4Addr->sin_addr.s_addr == 0) {
1267             FILLP_LOGERR("IPV4 NULL IP is not allowed");
1268             SET_ERRNO(FILLP_EINVAL);
1269             return ERR_SOCK_TYPE_ERR;
1270         }
1271     } else {
1272         struct sockaddr_in6 *ipv6Addr = (struct sockaddr_in6 *)name;
1273         if (nameLen < sizeof(struct sockaddr_in6)) {
1274             FILLP_LOGERR("nameLen is too less for ipv6 addr, nameLen:%u", nameLen);
1275             SET_ERRNO(FILLP_EINVAL);
1276             return ERR_SOCK_TYPE_ERR;
1277         }
1278 
1279         if (IPV6_ADDR_IS_NULL(ipv6Addr)) {
1280             FILLP_LOGERR("IPV6 NULL IP is not allowed");
1281             SET_ERRNO(FILLP_EINVAL);
1282             return ERR_SOCK_TYPE_ERR;
1283         }
1284     }
1285 
1286     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sock->index,
1287         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : FtConnect / FtBind, socket:%d nameLen:%d",
1288         sock->index, nameLen));
1289 
1290     return ERR_OK;
1291 }
1292 
SockGetRtt(FILLP_INT sockFd)1293 FILLP_ULLONG SockGetRtt(FILLP_INT sockFd)
1294 {
1295     FILLP_ULLONG rtt = 0;
1296     FILLP_UINT8 state;
1297     struct FtNetconn *conn = FILLP_NULL_PTR;
1298 
1299     /* errno is set inside the function upon failure */
1300     struct FtSocket *sock = SockApiGetAndCheck(sockFd);
1301     if (sock == FILLP_NULL_PTR) {
1302         return FILLP_NULL;
1303     }
1304 
1305     if (sock->netconn != FILLP_NULL_PTR) {
1306         conn = (struct FtNetconn *)sock->netconn;
1307         state = NETCONN_GET_STATE(conn);
1308         if (state == CONN_STATE_CONNECTED) {
1309             rtt = conn->calcRttDuringConnect;
1310         }
1311     }
1312 
1313     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1314 
1315     return rtt;
1316 }
1317 
SockConnect(FILLP_INT sockIndex,FILLP_CONST struct sockaddr * name,socklen_t nameLen)1318 FillpErrorType SockConnect(FILLP_INT sockIndex, FILLP_CONST struct sockaddr *name, socklen_t nameLen)
1319 {
1320     struct FtSocket *sock = SockApiGetAndCheck(sockIndex);
1321     struct SpungeConnectMsg connectMsg;
1322     FillpTraceDescriptSt fillpTrcDesc = FILLP_TRACE_DESC_INIT(FILLP_TRACE_DIRECT_SEND);
1323     FillpErrorType err;
1324 
1325     FILLP_LOGINF("fillp_sock_id:%d", sockIndex);
1326 
1327     /* errno is set inside the function upon failure */
1328     if (sock == FILLP_NULL_PTR) {
1329         return -1;
1330     }
1331 
1332     /* errno is set inside the function upon failure */
1333     err = SockBindConnectValidateParams(sock, name, nameLen);
1334     if (err != ERR_OK) {
1335         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1336         return -1;
1337     }
1338 
1339     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)sockIndex,
1340         (FILLP_UINT8 *)(void *)&fillpTrcDesc,
1341         "Entering Function : FtConnect->SockConnect  socket:%d nameLen:%d", sockIndex, nameLen));
1342 
1343     connectMsg.addr = (struct sockaddr_in *)name;
1344     connectMsg.addrLen = nameLen;
1345     connectMsg.sock = (void *)sock;
1346 
1347     err = SpungePostMsg(sock->inst, &connectMsg, MSG_TYPE_DO_CONNECT, FILLP_TRUE);
1348     if (err != ERR_OK) {
1349         FILLP_LOGERR("Failed to send message in SockConnect for socketId = %d", sockIndex);
1350         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1351         SET_ERRNO(FILLP_ENOBUFS);
1352         return -1;
1353     }
1354 
1355     if (!SOCK_IS_NONBLOCKING(sock)) {
1356         if (SYS_ARCH_SEM_WAIT(&sock->connBlockSem)) {
1357             FILLP_LOGERR("Error to wait connBlockSem");
1358             (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1359             SET_ERRNO(FILLP_ENOBUFS);
1360             return -1;
1361         }
1362     }
1363 
1364     err = sock->coreErrType[MSG_TYPE_DO_CONNECT];
1365     if (err != ERR_OK) {
1366         if (err != ERR_NONBLOCK_UNDERCONNECT) {
1367             FillpNetconnSetSafeErr(sock->netconn, err);
1368         } else {
1369             FillpNetconnSetSafeErr(sock->netconn, sock->netconn->lastErr);
1370         }
1371 
1372         SockSetError(sock, err);
1373         err = -1;
1374     }
1375 
1376     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1377     return err;
1378 }
1379 
SockBind(FILLP_INT sockIndex,FILLP_CONST struct sockaddr * name,FILLP_UINT32 nameLen)1380 FillpErrorType SockBind(FILLP_INT sockIndex, FILLP_CONST struct sockaddr *name, FILLP_UINT32 nameLen)
1381 {
1382     struct FtSocket *sock = SockApiGetAndCheck(sockIndex);
1383     FILLP_INT err = ERR_OK;
1384     struct SpungeBindMsg bindMsg;
1385 
1386     /* errno is set inside this function upon failure */
1387     if (sock == FILLP_NULL_PTR) {
1388         return -1;
1389     }
1390 
1391     /* errno is set inside this function upon failure */
1392     err = SockBindConnectValidateParams(sock, name, nameLen);
1393     if (err != ERR_OK) {
1394         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1395         return -1;
1396     }
1397 
1398     bindMsg.sock = (void *)sock;
1399     bindMsg.addr = (struct sockaddr_in *)name;
1400     bindMsg.addrLen = nameLen;
1401 
1402     FILLP_LOGINF("fillp_sock_id:%d,nameLen:%u,port:%u", sockIndex, nameLen, UTILS_GET_ADDRPORT(name));
1403 
1404     err = SpungePostMsg(sock->inst, &bindMsg, MSG_TYPE_DO_BIND, FILLP_TRUE);
1405     if (err != ERR_OK) {
1406         FILLP_LOGERR("Failed to post msg to fillp sock->index = %d", sock->index);
1407         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1408         SET_ERRNO(FILLP_ENOBUFS);
1409         return -1;
1410     }
1411 
1412     err = sock->coreErrType[MSG_TYPE_DO_BIND];
1413     FillpNetconnSetSafeErr(sock->netconn, err);
1414 
1415     FILLP_LOGINF("fillp_sock_id:%d,ret:%d", sockIndex, err);
1416 
1417     if (err != ERR_OK) {
1418         if (err == ERR_NO_REBIND) {
1419             FILLP_SOCK_SET_ERR(sock, FILLP_EADDRINUSE);
1420             SET_ERRNO(FILLP_EADDRINUSE);
1421         } else {
1422             FILLP_SOCK_SET_ERR(sock, FILLP_EINVAL);
1423             SET_ERRNO(FILLP_EINVAL);
1424         }
1425 
1426         err = -1;
1427     } else {
1428         FILLP_SOCK_SET_ERR(sock, ERR_OK);
1429     }
1430 
1431     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1432 
1433     return err;
1434 }
1435 
1436 #ifdef FILLP_LINUX
SockFcntl(FILLP_INT s,FILLP_INT cmd,FILLP_INT val)1437 FILLP_INT SockFcntl(FILLP_INT s, FILLP_INT cmd, FILLP_INT val)
1438 {
1439     struct FtSocket *sock;
1440     FILLP_INT ret = -1;
1441     FillpTraceDescriptSt fillpTrcDesc;
1442 
1443     sock = SockApiGetAndCheck(s);
1444     if (sock == FILLP_NULL_PTR) {
1445         return -1;
1446     }
1447 
1448     fillpTrcDesc.traceDirection = FILLP_TRACE_DIRECT_SEND;
1449     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)s,
1450         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : FtFcntl->SockFcntl socket:%d cmd:%d val:%d",
1451         s, cmd, val));
1452 
1453     switch (cmd) {
1454         case F_GETFL:
1455             ret = SOCK_IS_NONBLOCKING(sock) ? O_NONBLOCK : 0;
1456             break;
1457 
1458         case F_SETFL:
1459             if (((FILLP_UINT)val & ~(FILLP_UINT)O_NONBLOCK) == 0) {
1460                 /* only O_NONBLOCK, all other bits are zero */
1461                 SockSetNonblocking(sock, (FILLP_INT)((FILLP_UINT)val & (FILLP_UINT)O_NONBLOCK));
1462                 ret = 0;
1463             }
1464             break;
1465         default:
1466             ret = -1;
1467             FILLP_LOGERR("sock_fnctl:invalid cmd %d, ft_sock_id %d \r\n", cmd, s);
1468             break;
1469     }
1470 
1471     if (ret < 0) {
1472         SET_ERRNO(FILLP_EINVAL);
1473     }
1474 
1475     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1476     return ret;
1477 }
1478 #endif
1479 
SockIoctlsocket(FILLP_INT s,FILLP_SLONG cmd,FILLP_CONST FILLP_INT * val)1480 FILLP_INT SockIoctlsocket(FILLP_INT s, FILLP_SLONG cmd, FILLP_CONST FILLP_INT *val)
1481 {
1482     struct FtSocket *sock = FILLP_NULL_PTR;
1483     FillpTraceDescriptSt fillpTrcDesc;
1484 
1485     if (val == FILLP_NULL_PTR) {
1486         FILLP_LOGERR("SockIoctlsocket : Invalid input parameter : val is null\r\n");
1487         SET_ERRNO(FILLP_EINVAL);
1488         return -1;
1489     }
1490 
1491     sock = SockApiGetAndCheck(s);
1492     if (sock == FILLP_NULL_PTR) {
1493         return -1;
1494     }
1495 
1496     fillpTrcDesc.traceDirection = FILLP_TRACE_DIRECT_SEND;
1497     FILLP_APP_LM_FILLPCMDTRACE_OUTPUT((FILLP_TRACE_DIRECT_USER, sock->traceHandle, 0, (FILLP_UINT32)s,
1498         (FILLP_UINT8 *)(void *)&fillpTrcDesc, "Entering Function : SockIoctlsocket s: %d cmd: %ld\r\n",
1499         s, cmd));
1500 
1501     switch (cmd) {
1502         case FILLP_FIONBIO:
1503 
1504             if ((*val != 0) && (*val != 1)) {
1505                 FILLP_LOGERR("SockIoctlsocket:invalid val %d passed, Socket-%d \r\n", *val, s);
1506                 (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1507                 SET_ERRNO(FILLP_EINVAL);
1508                 return -1;
1509             }
1510 
1511             SockSetNonblocking(sock, *val);
1512 
1513             break;
1514 
1515         default:
1516             FILLP_LOGERR("SockIoctlsocket:invalid cmd %ld failed, Socket-%d \r\n", cmd, s);
1517 
1518             (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1519             SET_ERRNO(FILLP_EINVAL);
1520             return -1;
1521     }
1522 
1523     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1524     return FILLP_OK;
1525 }
1526 
SockGetnameCheckParam(FILLP_INT sockIndex,FILLP_CONST struct sockaddr * name,FILLP_CONST socklen_t * nameLen)1527 static struct FtSocket *SockGetnameCheckParam(FILLP_INT sockIndex, FILLP_CONST struct sockaddr *name,
1528     FILLP_CONST socklen_t *nameLen)
1529 {
1530     struct FtSocket *sock = FILLP_NULL_PTR;
1531     if (name == FILLP_NULL_PTR) {
1532         FILLP_LOGERR("fillp_sock_id:%d Input connect address is Invalid", sockIndex);
1533         SET_ERRNO(FILLP_EINVAL);
1534         return FILLP_NULL_PTR;
1535     }
1536 
1537     sock = SockApiGetAndCheck(sockIndex);
1538     if (sock == FILLP_NULL_PTR) {
1539         return FILLP_NULL_PTR;
1540     }
1541 
1542     /* non-negative number cannot be less than 0 */
1543     if ((nameLen == FILLP_NULL_PTR) || (*nameLen == 0) ||
1544         ((sock->sockAddrType == AF_INET) && (*nameLen < (socklen_t)sizeof(struct sockaddr_in))) ||
1545         ((sock->sockAddrType == AF_INET6) && (*nameLen < (socklen_t)sizeof(struct sockaddr_in6)))) {
1546         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1547         FILLP_LOGERR("fillp_sock_id:%d Input connect address length is Invalid", sockIndex);
1548         SET_ERRNO(FILLP_EINVAL);
1549         return FILLP_NULL_PTR;
1550     }
1551 
1552     return sock;
1553 }
1554 
SockGetsockname(FILLP_INT sockIndex,struct sockaddr * name,socklen_t * nameLen)1555 FILLP_INT SockGetsockname(FILLP_INT sockIndex, struct sockaddr *name, socklen_t *nameLen)
1556 {
1557     struct FtSocket *sock = SockGetnameCheckParam(sockIndex, name, nameLen);
1558     struct SockOsSocket *osSock = FILLP_NULL_PTR;
1559     FillpErrorType err = ERR_OK;
1560     size_t addrSize;
1561 
1562     FILLP_LOGINF("fillp_sock_id:%d", sockIndex);
1563 
1564     if (sock == FILLP_NULL_PTR) {
1565         return -1;
1566     }
1567 
1568     if (NETCONN_GET_STATE(sock->netconn) == CONN_STATE_CONNECTED) {
1569         if (sock->sockAddrType == AF_INET) {
1570             addrSize = sizeof(struct sockaddr_in);
1571             if (*nameLen > (socklen_t)addrSize) {
1572                 *nameLen = (socklen_t)addrSize;
1573             }
1574             (void)memcpy_s(name, *nameLen, &(sock->netconn->pcb->localAddr), *nameLen);
1575         } else if (sock->sockAddrType == AF_INET6) {
1576             addrSize = sizeof(struct sockaddr_in6);
1577             if (*nameLen > (socklen_t)addrSize) {
1578                 *nameLen = (socklen_t)addrSize;
1579             }
1580             (void)memcpy_s(name, *nameLen, &(sock->netconn->pcb->localAddr), *nameLen);
1581         }
1582     } else {
1583         osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
1584         if (!OS_SOCK_OPS_FUNC_VALID(osSock, getSockName)) {
1585             SET_ERRNO(FILLP_EINVAL);
1586             err = -1;
1587         } else {
1588             err = osSock->ioSock->ops->getSockName(osSock->ioSock, name, nameLen);
1589         }
1590     }
1591 
1592     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1593     FILLP_LOGINF("get sock name finished, fillp_sock_id:%d, err:%d", sockIndex, err);
1594 
1595     if (err != ERR_OK) {
1596         err = -1;
1597     }
1598 
1599     return err;
1600 }
1601 
1602 /* This interface do not check if socket is connected or not, just give whatever values
1603     are stored in cb, if application call before remote address is set,
1604     then it will cause */
SockGetpeername(FILLP_INT sockIndex,struct sockaddr * name,socklen_t * nameLen)1605 FILLP_INT SockGetpeername(FILLP_INT sockIndex, struct sockaddr *name, socklen_t *nameLen)
1606 {
1607     struct FtSocket *sock = SockGetnameCheckParam(sockIndex, name, nameLen);
1608     FillpErrorType err = ERR_OK;
1609     FILLP_UINT8 state;
1610     size_t addrSize;
1611 
1612     FILLP_LOGINF("SockGetpeername: fillp_sock_id:%d", sockIndex);
1613 
1614     if (sock == FILLP_NULL_PTR) {
1615         return -1;
1616     }
1617 
1618     state = NETCONN_GET_STATE(sock->netconn);
1619     if (state != CONN_STATE_CONNECTED) {
1620         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1621         FILLP_LOGERR("SockGetpeername: netcon socket state is incorrect for sock=%d, state = %u\r\n", sockIndex, state);
1622         SET_ERRNO(FILLP_ENOTCONN);
1623         return -1;
1624     }
1625 
1626     if (sock->sockAddrType == AF_INET) {
1627         addrSize = sizeof(struct sockaddr_in);
1628         if (*nameLen > (socklen_t)addrSize) {
1629             *nameLen = (socklen_t)addrSize;
1630         }
1631         (void)memcpy_s(name, *nameLen, &(sock->netconn->pcb->remoteAddr), *nameLen);
1632     } else if (sock->sockAddrType == AF_INET6) {
1633         addrSize = sizeof(struct sockaddr_in6);
1634         if (*nameLen > (socklen_t)addrSize) {
1635             *nameLen = (socklen_t)addrSize;
1636         }
1637         (void)memcpy_s(name, *nameLen, &(sock->netconn->pcb->remoteAddr), *nameLen);
1638     }
1639 
1640     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1641     FILLP_LOGINF("SockGetpeername: return sock=%d, err:%d", sockIndex, err);
1642 
1643     return err;
1644 }
1645 
SockGetSockEvt(FILLP_INT s)1646 FILLP_INT SockGetSockEvt(FILLP_INT s)
1647 {
1648     FILLP_UINT ret = 0;
1649     struct FtSocket *sock = SockApiGetAndCheck(s);
1650 
1651     FILLP_LOGDBG("fillp_sock_id:%d", s);
1652 
1653     if (sock == FILLP_NULL_PTR) {
1654         return 0;
1655     }
1656 
1657     if (SYS_ARCH_ATOMIC_READ(&sock->rcvEvent)) {
1658         ret |= SPUNGE_EPOLLIN;
1659     }
1660 
1661     if ((SYS_ARCH_ATOMIC_READ(&sock->sendEvent)) && (SYS_ARCH_ATOMIC_READ(&sock->sendEventCount) > 0)) {
1662         ret |= SPUNGE_EPOLLOUT;
1663     }
1664 
1665     if (sock->errEvent) {
1666         ret |= sock->errEvent;
1667     }
1668     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1669     return (FILLP_INT)ret;
1670 }
1671 
1672 /* Set the blocking status of FtSocket
1673 
1674     The flag (which contains the socket options is in FtSocket and NOT in netconn CB)
1675     is in FtSocket structure, this is because: Application can set the socket to
1676     nonblock just after calling FtSocket (before ft_connet/FtAccept), but the
1677     netconn CB will be available only during FtConnect/FtAccept.
1678 */
SockSetNonblocking(struct FtSocket * sock,FILLP_INT val)1679 void SockSetNonblocking(struct FtSocket *sock, FILLP_INT val)
1680 {
1681     if ((val > 0) && SOCK_IS_BLOCKING(sock)) {
1682         sock->flags |= (FILLP_UINT16)SOCK_FLAG_NON_BLOCKING;
1683     } else if ((val == 0) && SOCK_IS_NONBLOCKING(sock)) {
1684         sock->flags &= (FILLP_UINT16)(~SOCK_FLAG_NON_BLOCKING);
1685     }
1686 }
1687 
SockEventInfoGet(int s,FtEventCbkInfo * info)1688 FILLP_INT SockEventInfoGet(int s, FtEventCbkInfo *info)
1689 {
1690     FILLP_INT ret;
1691     struct FtSocket *sock = FILLP_NULL_PTR;
1692     struct SpungeEvtInfoMsg msg;
1693 
1694     if (info == FILLP_NULL_PTR) {
1695         SET_ERRNO(FILLP_EINVAL);
1696         return -1;
1697     }
1698 
1699     sock = SockApiGetAndCheck(s);
1700     if (sock == FILLP_NULL_PTR) {
1701         SET_ERRNO(FILLP_EINVAL);
1702         return -1;
1703     }
1704 
1705     msg.sock = (void *)sock;
1706     msg.info = info;
1707     ret = SpungePostMsg(sock->inst, &msg, MSG_TYPE_GET_EVENT_INFO, FILLP_TRUE);
1708     if (ret != ERR_OK) {
1709         SET_ERRNO(FILLP_EINVAL);
1710         FILLP_LOGERR("Failed to post msg to fillp sock->index = %d", sock->index);
1711         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1712         return -1;
1713     }
1714 
1715     ret = sock->coreErrType[MSG_TYPE_GET_EVENT_INFO];
1716     if (ret != ERR_OK) {
1717         SET_ERRNO(FILLP_EINVAL);
1718         FILLP_LOGERR("fillp_sock_id:%d,ret:%d", sock->index, ret);
1719         (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1720         return -1;
1721     }
1722 
1723     (void)SYS_ARCH_RWSEM_RDPOST(&sock->sockConnSem);
1724     return 0;
1725 }
1726 
1727 #ifdef __cplusplus
1728 }
1729 #endif
1730