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