diff options
author | 2019-04-30 17:40:53 +0530 | |
---|---|---|
committer | 2019-05-20 18:14:40 +0530 | |
commit | a826fe833d3f2a8fe2673fa05811fe1a22baf045 (patch) | |
tree | da11a17c46ca9b8a002a52a290628574fa3f5eda /stacks/lwip_stack/lwip_src/socket/stackx_udp.c | |
parent | 3e6bf7b64eea418c59959c18750261b815b2892c (diff) |
Feature: 19.04 part 1
Change-Id: Ibba924b8deca1f246b9dcb12d89d085b6fd33046
Signed-off-by: charan makkina <charan795m@gmail.com>
Diffstat (limited to 'stacks/lwip_stack/lwip_src/socket/stackx_udp.c')
-rw-r--r-- | stacks/lwip_stack/lwip_src/socket/stackx_udp.c | 1153 |
1 files changed, 0 insertions, 1153 deletions
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_udp.c b/stacks/lwip_stack/lwip_src/socket/stackx_udp.c deleted file mode 100644 index 1f382cf..0000000 --- a/stacks/lwip_stack/lwip_src/socket/stackx_udp.c +++ /dev/null @@ -1,1153 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "stackx_prot_com.h" -#include "stackx_msg_handler.h" -#include "stackx_pbuf.h" -#include "stackx_epoll_api.h" -#include "stackx_err.h" -#include "nstack_securec.h" -#include "common_pal_bitwide_adjust.h" -#include "stackx_cfg.h" -#include <netinet/in.h> -#ifdef HAL_LIB -#else -#include "rte_memcpy.h" -#endif - -#define SPL_PBUF_UDP_LEN (SPL_FRAME_MTU + SPL_PBUF_LINK_HLEN) -#define L2_L3_ROOM_LEN (SPL_PBUF_LINK_HLEN + SPL_PBUF_IP_HLEN) -#define L4_ROOM_LEN SPL_PBUF_UDP_HLEN - -/***************************************************************************** -* Prototype : sbr_udp_socket -* Description : create socket -* Input : sbr_socket_t * sk -* int domain -* int type -* int protocol -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_socket (sbr_socket_t * sk, int domain, int type, int protocol) -{ - if (sbr_malloc_conn_for_sk (sk, SPL_NETCONN_UDP) != 0) - { - return -1; - } - - int ret = sbr_handle_socket (sk, SPL_NETCONN_UDP, 0); - if (ret != 0) - { - sbr_free_conn_from_sk (sk); - return ret; - } - - ss_set_nonblock_flag (sbr_get_conn (sk), (type & O_NONBLOCK)); - ss_set_send_event (sbr_get_conn (sk), 1); - return ret; -} - -/***************************************************************************** -* Prototype : sbr_udp_bind -* Description : udp bind -* Input : sbr_socket_t * sk -* const struct sockaddr * name -* socklen_t namelen -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_bind (sbr_socket_t * sk, const struct sockaddr *name, - socklen_t namelen) -{ - const struct sockaddr_in *addr_in = (const struct sockaddr_in *) name; - - NSSBR_LOGINF ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, - spl_inet_ntoa (addr_in->sin_addr), ntohs (addr_in->sin_port), - sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk))); - spl_ip_addr_t local_addr; - inet_addr_to_ipaddr (&local_addr, &addr_in->sin_addr); - u16 local_port = addr_in->sin_port; - return sbr_handle_bind (sk, &local_addr, ntohs (local_port)); -} - -/***************************************************************************** -* Prototype : sbr_udp_listen -* Description : unsupport -* Input : sbr_socket_t * sk -* int backlog -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_listen (sbr_socket_t * sk, int backlog) -{ - NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); - sbr_set_sk_errno (sk, EOPNOTSUPP); - return -1; -} - -/***************************************************************************** -* Prototype : sbr_udp_accept -* Description : unsupport -* Input : sbr_socket_t * sk -* sbr_socket_t * new_sk -* struct sockaddr * addr -* socklen_t * addrlen -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_accept (sbr_socket_t * sk, sbr_socket_t * new_sk, - struct sockaddr *addr, socklen_t * addrlen) -{ - NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); - sbr_set_sk_errno (sk, EOPNOTSUPP); - return -1; -} - -/***************************************************************************** -* Prototype : sbr_udp_accept4 -* Description : unsupport -* Input : sbr_socket_t * sk -* sbr_socket_t * new_sk -* struct sockaddr * addr -* socklen_t * addrlen -* int flags -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_accept4 (sbr_socket_t * sk, sbr_socket_t * new_sk, - struct sockaddr *addr, socklen_t * addrlen, int flags) -{ - NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); - sbr_set_sk_errno (sk, EOPNOTSUPP); - return -1; -} - -/***************************************************************************** -* Prototype : sbr_udp_connect -* Description : udp connect -* Input : sbr_socket_t * sk -* const struct sockaddr * name -* socklen_t namelen -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_connect (sbr_socket_t * sk, const struct sockaddr *name, - socklen_t namelen) -{ - const struct sockaddr_in *addr_in = (const struct sockaddr_in *) name; - - NSSBR_LOGINF ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, - spl_inet_ntoa (addr_in->sin_addr), ntohs (addr_in->sin_port), - sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk))); - spl_ip_addr_t remote_addr; - - inet_addr_to_ipaddr (&remote_addr, &addr_in->sin_addr); - u16 remote_port = addr_in->sin_port; - - spl_ip_addr_t local_addr = { IPADDR_ANY }; - - return sbr_handle_connect (sk, &remote_addr, ntohs (remote_port), - &local_addr); -} - -/***************************************************************************** -* Prototype : sbr_udp_shutdown -* Description : udp shutdown -* Input : sbr_socket_t * sk -* int how -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_shutdown (sbr_socket_t * sk, int how) -{ - ss_set_shut_status (sbr_get_conn (sk), how); - NSSBR_LOGERR ("type is not TCP]fd=%d", sk->fd); - sbr_set_sk_errno (sk, EOPNOTSUPP); - return -1; -} - -/***************************************************************************** -* Prototype : sbr_udp_getsockname -* Description : get sock name -* Input : sbr_socket_t * sk -* struct sockaddr * name -* socklen_t * namelen -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_getsockname (sbr_socket_t * sk, struct sockaddr *name, - socklen_t * namelen) -{ - return sbr_handle_get_name (sk, name, namelen, SBR_GET_SOCK_NAME); -} - -/***************************************************************************** -* Prototype : sbr_udp_getpeername -* Description : get peer name -* Input : sbr_socket_t * sk -* struct sockaddr * name -* socklen_t * namelen -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_getpeername (sbr_socket_t * sk, struct sockaddr *name, - socklen_t * namelen) -{ - return sbr_handle_get_name (sk, name, namelen, SBR_GET_PEER_NAME); -} - -/***************************************************************************** -* Prototype : sbr_udp_getsockopt -* Description : get sockopt -* Input : sbr_socket_t * sk -* int level -* int optname -* void * optval -* socklen_t * optlen -* Output : None -* Return Value : int -* Calls : -* Called By : -* -*****************************************************************************/ -int -sbr_udp_getsockopt (sbr_socket_t * sk, int level, int optname, void *optval, - socklen_t * optlen) -{ - int err = 0; - - switch (level) - { - case SOL_SOCKET: - err = sbr_getsockopt_sol_socket (sk, optname, optval, *optlen); - break; - case IPPROTO_IP: - err = sbr_getsockopt_ipproto_ip (optname, optval, *optlen); - break; - - case NSTACK_SOCKOPT: - if ((optname == NSTACK_SEM_SLEEP) || (*optlen < sizeof (u32_t))) - { - *(u32_t *) optval = - sbr_get_fd_share (sk)->block_polling_time / 1000; - NSSOC_LOGINF - ("udp get recv sleep time success]usleep time=%d,fd=%d", - sbr_get_fd_share (sk)->block_polling_time, sk->fd); - return ERR_OK; - } - else - { - NSSOC_LOGINF ("get recv sleep time failed]fd=%d", sk->fd); - sbr_set_sk_io_errno (sk, EINVAL); - return -1; - } - - default: - err = ENOPROTOOPT; - break; - } - - if (err != 0) - { - NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level, - optname, err); - /* for option not support ,getsockopt() should return fail */ - sbr_set_sk_errno (sk, err); - return -1; - } - - return sbr_handle_getsockopt (sk, level, optname, optval, optlen); -} - -/***************************************************************************** -* Prototype : sbr_udp_setsockopt -* Description : set sockopt -* Input : sbr_socket_t * sk -* int level -* int optname -* const void * optval -* socklen_t optlen -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_setsockopt (sbr_socket_t * sk, int level, int optname, - const void *optval, socklen_t optlen) -{ - NSSBR_LOGDBG ("udp setsockopt]fd=%d,level=%d,optname=%d", sk->fd, level, - optname); - int err = 0; - switch (level) - { - case SOL_SOCKET: - err = - sbr_setsockopt_sol_socket (sk, optname, optval, optlen, - SPL_NETCONN_UDP); - break; - case IPPROTO_IP: - err = - sbr_setsockopt_ipproto_ip (optname, optval, optlen, SPL_NETCONN_UDP); - break; - case NSTACK_SOCKOPT: - { - u32_t sleep_time = *(u32_t *) optval; - /*sleep time should less than 1s */ - if ((optname == NSTACK_SEM_SLEEP) && (optlen >= sizeof (u32_t)) - && (sleep_time < 1000000)) - { - sbr_get_fd_share (sk)->block_polling_time = sleep_time * 1000; - NSSOC_LOGINF - ("udp set recv sleep time success]usleep time=%d,fd=%d", - sbr_get_fd_share (sk)->block_polling_time, sk->fd); - return ERR_OK; - } - else - { - NSSOC_LOGINF ("set recv sleep time failed]fd=%d", sk->fd); - sbr_set_sk_io_errno (sk, EINVAL); - return -1; - } - } - - default: - err = ENOPROTOOPT; - break; - } - - if (err != 0) - { - NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level, - optname, err); - - if (ENOPROTOOPT == err) - { - return 0; - } - else - { - sbr_set_sk_errno (sk, err); - return -1; - } - } - - return sbr_handle_setsockopt (sk, level, optname, optval, optlen); -} - -static inline int -sbr_udp_get_from_addr (sbr_socket_t * sk, struct sockaddr *from, - socklen_t * fromlen, struct spl_netbuf *buf) -{ - int ret; - u16 port = netbuf_fromport (buf); - spl_ip_addr_t *addr = netbuf_fromaddr (buf); - - ret = (from - && fromlen) ? sbr_get_sockaddr_and_len (port, addr, from, - fromlen) : 0; - if (0 != ret) - { - sbr_set_sk_io_errno (sk, EINVAL); - NSSBR_LOGERR ("sbr_udp_get_from_addr]fd=%d", sk->fd); - return -1; - } - - return 0; -} - -/***************************************************************************** -* Prototype : sbr_udp_recv_from_ring -* Description : recv buf from ring -* Input : sbr_socket_t * sk -* struct spl_netbuf ** buf -* i32 timeout -* Output : None -* Return Value : static inline int -* Calls : -* Called By : -* -*****************************************************************************/ -static inline int -sbr_udp_recv_from_ring (sbr_socket_t * sk, struct spl_netbuf **buf, - i32 timeout) -{ - void *p = NULL; - spl_netconn_t *conn = sbr_get_conn (sk); - - if (sbr_dequeue_buf (sk, &p, timeout) != 0) - { - return -1; - } - - *buf = (struct spl_netbuf *) ((char *) p + sizeof (struct spl_pbuf)); - ss_sub_recv_event (conn); - return 0; -} - -/***************************************************************************** -* Prototype : _sbr_udp_recvfrom -* Description : base recvfrom,without lock -* Input : sbr_socket_t * sk -* void * mem -* size_t len -* int flags -* struct sockaddr * from -* socklen_t * fromlen -* Output : None -* Return Value : static inline int -* Calls : -* Called By : -* -*****************************************************************************/ -static inline int -_sbr_udp_recvfrom (sbr_socket_t * sk, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t * fromlen) -{ - struct spl_netbuf *buf = NULL; - struct spl_pbuf *p; - u32 buflen; - u32 copylen; - u32 off = 0; - - if (sbr_get_fd_share (sk)->lastdata) - { - buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); - } - else - { - if ((flags & MSG_DONTWAIT) || ss_is_nonblock_flag (sbr_get_conn (sk))) - { - /* - * return with last err when - * some fatal err occurs, for example, spl just recovered from a fault. - */ - int err = ss_get_last_errno (sbr_get_conn (sk)); - if (SPL_ERR_IS_FATAL (err)) - { - NSSBR_LOGDBG ("connection fatal error]sk->fd=%d,errno=%d", - sk->fd, err); - sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err)); - return -1; - } - - if (ss_get_recv_event (sbr_get_conn (sk)) <= 0) - { - NSSBR_LOGDBG ("no recv event]fd=%d", sk->fd); - sbr_set_sk_io_errno (sk, EWOULDBLOCK); - return -1; - } - } - - if (sbr_udp_recv_from_ring - (sk, &buf, sbr_get_fd_share (sk)->recv_timeout) != 0) - { - return -1; - } - - sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (buf); - } - - p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); - buflen = p->tot_len; - - if (mem) - { - copylen = len > buflen ? buflen : len; - - if ((copylen > 0) && 0 == spl_pbuf_copy_partial (p, mem, copylen, 0)) - { - NSSBR_LOGERR ("copy failed]fd=%d", sk->fd); - sbr_set_sk_io_errno (sk, EFAULT); - return -1; - } - - off += copylen; - } - - if (sbr_udp_get_from_addr (sk, from, fromlen, buf) != 0) - { - return -1; - } - - if (!(flags & MSG_PEEK)) - { - sbr_get_fd_share (sk)->lastdata = NULL; - sbr_com_free_recv_buf (sk, (struct spl_pbuf *) ADDR_SHTOL (buf->p)); - } - - return off; -} - -/***************************************************************************** -* Prototype : sbr_udp_recvfrom -* Description : recv from -* Input : sbr_socket_t * sk -* void * mem -* size_t len -* int flags -* struct sockaddr * from -* socklen_t * fromlen -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_recvfrom (sbr_socket_t * sk, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t * fromlen) -{ - sbr_com_lock_recv (sk); - int ret = _sbr_udp_recvfrom (sk, mem, len, flags, from, fromlen); - sbr_com_unlock_recv (sk); - return ret; -} - -/***************************************************************************** -* Prototype : sbr_udp_recvdata -* Description : recv data -* Input : sbr_socket_t * sk -* const struct iovec* iov -* int iovcnt -* struct spl_netbuf *buf -* Output : None -* Return Value : static inline -* Calls : -* Called By : -* -*****************************************************************************/ -static inline int -sbr_udp_recvdata (sbr_socket_t * sk, const struct iovec *iov, int iovcnt, - int flags, struct sockaddr *from, socklen_t * fromlen) -{ - sbr_com_lock_recv (sk); - if (-1 == _sbr_udp_recvfrom (sk, NULL, 0, MSG_PEEK, from, fromlen)) - { - sbr_com_unlock_recv (sk); - return -1; - } - - struct spl_netbuf *buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); - struct spl_pbuf *p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); - u32 buflen = p->tot_len; - u32 copylen = 0; - u32 offset = 0; - - int i; - - for (i = 0; i < iovcnt; ++i) - { - if (!iov[i].iov_base || (0 == iov[i].iov_len)) - { - continue; - } - - copylen = buflen > iov[i].iov_len ? iov[i].iov_len : buflen; - if ((copylen > 0) - && 0 == spl_pbuf_copy_partial (p, iov[i].iov_base, copylen, offset)) - { - NSSBR_LOGERR ("copy failed]fd=%d", sk->fd); - goto done; - } - - offset += copylen; - buflen -= copylen; - - if (0 == buflen) - { - goto done; - } - } - -done: - if (!(flags & MSG_PEEK)) - { - sbr_get_fd_share (sk)->lastdata = NULL; - sbr_com_free_recv_buf (sk, (struct spl_pbuf *) ADDR_SHTOL (buf->p)); - } - - sbr_com_unlock_recv (sk); - return offset; -} - -/***************************************************************************** -* Prototype : sbr_udp_readv -* Description : readv -* Input : sbr_socket_t* sk -* const struct iovec* iov -* int iovcnt -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_readv (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) -{ - return sbr_udp_recvdata (sk, iov, iovcnt, 0, NULL, NULL); -} - -/***************************************************************************** -* Prototype : sbr_udp_recvmsg -* Description : recv msg -* Input : sbr_socket_t* sk -* struct msghdr* msg -* int flags -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_recvmsg (sbr_socket_t * sk, struct msghdr *msg, int flags) -{ - return sbr_udp_recvdata (sk, msg->msg_iov, msg->msg_iovlen, flags, - (struct sockaddr *) msg->msg_name, - &msg->msg_namelen); -} - -/***************************************************************************** -* Prototype : sbr_copy_iov -* Description : copy iov -* Input : sbr_socket_t * sk -* const struct iovec * iov -* int iovcnt -* struct spl_pbuf* buf -* Output : None -* Return Value : static inline int -* Calls : -* Called By : -* -*****************************************************************************/ -static inline int -sbr_copy_iov (sbr_socket_t * sk, const struct iovec *iov, int iovcnt, - struct spl_pbuf *buf) -{ - u32 buf_left = buf->len; - i8 *buf_data = (i8 *) ADDR_SHTOL (buf->payload); - u32 iov_left; - i8 *iov_data; - u32 copy_len; - - int i; - - for (i = 0; i < iovcnt; ++i) - { - if (!iov[i].iov_base || (0 == iov[i].iov_len)) - { - continue; - } - - iov_left = (u32) iov[i].iov_len; /* to u32 is ok,len is checked in sbr_udp_senddata */ - iov_data = (i8 *) iov[i].iov_base; - while (iov_left) - { - copy_len = buf_left > iov_left ? iov_left : buf_left; - - if (NULL == common_memcpy (buf_data, iov_data, copy_len)) - { - NSSBR_LOGERR ("common_memcpy error]fd=%d", sk->fd); - sbr_set_sk_errno (sk, EFAULT); - return -1; - } - - buf_data += copy_len; - buf_left -= copy_len; - iov_data += copy_len; - iov_left -= copy_len; - if (0 == buf_left) - { - buf = (struct spl_pbuf *) ADDR_SHTOL (buf->next); - if (buf) - { - buf_left = buf->len; - buf_data = (i8 *) ADDR_SHTOL (buf->payload); - } - else - { - return 0; - } - } - } - } - - return 0; -} - -/***************************************************************************** -* Prototype : sbr_udp_senddata -* Description : send data -* Input : sbr_socket_t * sk -* const struct iovec * iov -* int iovcnt -* int flags -* const struct sockaddr * to -* socklen_t tolen -* Output : None -* Return Value : static inline int -* Calls : -* Called By : -* -*****************************************************************************/ -static inline int -sbr_udp_senddata (sbr_socket_t * sk, const struct iovec *iov, int iovcnt, - int flags, const struct sockaddr *to, socklen_t tolen) -{ - size_t size = 0; - int iov_idx; - - for (iov_idx = 0; iov_idx < iovcnt; ++iov_idx) - { - if ((SPL_MAX_UDP_MSG_LEN - size) < iov[iov_idx].iov_len) - { - NSSBR_LOGERR - ("size > SPL_MAX_UDP_MSG_LEN]fd=%d,SPL_MAX_UDP_MSG_LEN=%u", - sk->fd, SPL_MAX_UDP_MSG_LEN); - sbr_set_sk_io_errno (sk, EMSGSIZE); - return -1; - } - - size += iov[iov_idx].iov_len; - } - - if (to == NULL) - { - /* if not bind , then dest address should not be NULL */ - if (IPADDR_ANY == ss_get_remote_ip (sbr_get_conn (sk))->addr) - { - NSSBR_LOGERR ("dest address is null]fd=%d", sk->fd); - sbr_set_sk_io_errno (sk, EDESTADDRREQ); - return -1; - } - } - else if (to->sa_family != AF_INET) - { - NSSBR_LOGERR ("invalid address family]fd=%d,family=%d", sk->fd, - to->sa_family); - sbr_set_sk_io_errno (sk, EAFNOSUPPORT); - return -1; - } - else if (tolen != sizeof (struct sockaddr_in)) - { - NSSBR_LOGERR ("invalid address len]fd=%d,tolen=%u", sk->fd, tolen); - sbr_set_sk_io_errno (sk, EINVAL); - return -1; - } - - struct spl_netbuf buf; - const struct sockaddr_in *to_in = (const struct sockaddr_in *) to; - buf.p = NULL; - if (to_in) - { - NSSBR_LOGDBG ("fd=%d,addr=%s,port=%d,conn=%p,private_data=%p", sk->fd, - spl_inet_ntoa (to_in->sin_addr), ntohs (to_in->sin_port), - sbr_get_conn (sk), - ss_get_private_data (sbr_get_conn (sk))); - inet_addr_to_ipaddr (&buf.addr, &to_in->sin_addr); - netbuf_fromport (&buf) = ntohs (to_in->sin_port); - } - else - { - spl_ip_addr_set_any (&buf.addr); - netbuf_fromport (&buf) = 0; - } - - spl_ip_addr_t local_ip = { IPADDR_ANY }; - - int err = ss_get_last_errno (sbr_get_conn (sk)); - if (SPL_ERR_IS_FATAL (err)) - { - NS_LOG_CTRL (LOG_CTRL_SEND, LOGSBR, "NSSBR", NSLOG_ERR, - "connection fatal error!err=%d", err); - sbr_set_sk_errno (sk, sbr_spl_err_to_errno (err)); - return -1; - } - - u16 remain_len = size; //+ head_room_len; - struct spl_pbuf *p = NULL; - PRIMARY_ADDR struct spl_pbuf *header = NULL; - struct spl_pbuf **tail = &header; - u16 head_len = L2_L3_ROOM_LEN + L4_ROOM_LEN; - u16 copy_len; - u16 alloc_len; - - do - { - copy_len = - remain_len > - (SPL_PBUF_UDP_LEN - head_len) ? (SPL_PBUF_UDP_LEN - - head_len) : remain_len; - alloc_len = head_len + copy_len; - p = sbr_malloc_tx_pbuf (alloc_len, head_len); - if (unlikely (!p)) - { - NSSBR_LOGDBG ("malloc pbuf failed]fd=%d", sk->fd); - sbr_set_sk_io_errno (sk, ENOMEM); - sbr_handle_free_send_buf (sk, - (struct spl_pbuf *) ADDR_SHTOL (header)); - // ss_set_send_event(sbr_get_conn(sk), 0); - return -1; - } - - struct spl_pbuf *tmp = (struct spl_pbuf *) ADDR_SHTOL (header); - while (tmp) - { - tmp->tot_len += p->len; - tmp = (struct spl_pbuf *) ADDR_SHTOL (tmp->next); - } - - *tail = (struct spl_pbuf *) ADDR_LTOSH (p); /* header will changed to share */ - tail = &p->next; - - remain_len -= copy_len; - head_len = L2_L3_ROOM_LEN; - } - while (remain_len); - - /*udp support len=0 */ - if (size != 0) - { - if (sbr_copy_iov - (sk, iov, iovcnt, (struct spl_pbuf *) ADDR_SHTOL (header)) != 0) - { - sbr_handle_free_send_buf (sk, - (struct spl_pbuf *) ADDR_SHTOL (header)); - return -1; - } - } - - buf.p = header; - err = sbr_handle_udp_send (sk, &buf, &local_ip); - if (0 == err) - { - epoll_triggle_event_from_api (sk, EPOLL_API_OP_SEND); - //ss_set_send_event(sbr_get_conn(sk), 1); - return size; - } - else - { - sbr_handle_free_send_buf (sk, (struct spl_pbuf *) ADDR_SHTOL (buf.p)); - return -1; - } - -} - -/***************************************************************************** -* Prototype : sbr_udp_sendto -* Description : sendto -* Input : sbr_socket_t * sk -* const void * data -* size_t size -* int flags -* const struct sockaddr * to -* socklen_t tolen -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_sendto (sbr_socket_t * sk, const void *data, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - struct iovec iov; - - iov.iov_base = (void *) data; - iov.iov_len = size; - return sbr_udp_senddata (sk, &iov, 1, flags, to, tolen); -} - -/***************************************************************************** -* Prototype : sbr_udp_send -* Description : send -* Input : sbr_socket_t * sk -* const void * data -* size_t size -* int flags -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_send (sbr_socket_t * sk, const void *data, size_t size, int flags) -{ - return sk->fdopt->sendto (sk, data, size, flags, NULL, 0); -} - -/***************************************************************************** -* Prototype : sbr_udp_sendmsg -* Description : send msg -* Input : sbr_socket_t * sk -* const struct msghdr * pmsg -* int flags -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_sendmsg (sbr_socket_t * sk, const struct msghdr *pmsg, int flags) -{ - return sbr_udp_senddata (sk, pmsg->msg_iov, pmsg->msg_iovlen, flags, - (struct sockaddr *) pmsg->msg_name, - pmsg->msg_namelen); -} - -/***************************************************************************** -* Prototype : sbr_udp_writev -* Description : writev -* Input : sbr_socket_t * sk -* const struct iovec * iov -* int iovcnt -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_writev (sbr_socket_t * sk, const struct iovec *iov, int iovcnt) -{ - return sbr_udp_senddata (sk, iov, iovcnt, 0, NULL, 0); -} - -/***************************************************************************** -* Prototype : sbr_udp_fcntl -* Description : fcntl -* Input : sbr_socket_t * sk -* int cmd -* long arg -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_fcntl (sbr_socket_t * sk, int cmd, long arg) -{ - int ret = 0; - - switch (cmd) - { - case F_GETFL: - ret = ss_get_nonblock_flag (sbr_get_conn (sk)); - NSSBR_LOGDBG ("F_GETFL]fd=%d,ret=%d", sk->fd, ret); - break; - case F_SETFL: - if (arg & O_NONBLOCK) - { - NSSBR_LOGDBG ("F_SETFL set O_NONBLOCK val]fd=%d,arg=%ld", sk->fd, - arg); - ss_set_nonblock_flag (sbr_get_conn (sk), (arg & O_NONBLOCK)); - } - else - { - NSSBR_LOGDBG ("F_SETFL clean O_NONBLOCK val]fd=%d,arg=%ld", sk->fd, - arg); - ss_set_nonblock_flag (sbr_get_conn (sk), 0); - } - - break; - default: - NSSBR_LOGERR ("cmd is not support]fd=%d,cmd=%d", sk->fd, cmd); - ret = -1; - sbr_set_sk_errno (sk, EINVAL); - - break; - } - - return ret; -} - -/***************************************************************************** -* Prototype : sbr_udp_ioctl -* Description : ioctl -* Input : sbr_socket_t * sk -* unsigned long cmd -* void * arg -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_ioctl (sbr_socket_t * sk, unsigned long cmd, void *arg) -{ - int ret = 0; - - switch (cmd) - { - case FIONREAD: - { - if (!sbr_com_try_lock_recv (sk)) - { - return 0; - } - - struct spl_pbuf *p = NULL; - struct spl_netbuf *buf = NULL; - if (!sbr_get_fd_share (sk)->lastdata) - { - ret = sbr_udp_recv_from_ring (sk, &buf, -1); - if (ret != 0) - { - sbr_com_unlock_recv (sk); - return EWOULDBLOCK == errno ? 0 : -1; - } - - sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (buf); - p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); - } - else - { - buf = - (struct spl_netbuf *) - ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); - p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); - } - - *((u32 *) arg) = p->tot_len; - sbr_com_unlock_recv (sk); - } - break; - case FIONBIO: - { - u8 val = 0; - - if (arg && *(u32 *) arg) - { - val = 1; - } - - ss_set_nonblock_flag (sbr_get_conn (sk), val); - NSSBR_LOGDBG ("FIONBIO]fd=%d,val=%u", sk->fd, val); - } - break; - default: - { - NSSBR_LOGERR ("cmd is not support]fd=%d,cmd=%lu", sk->fd, cmd); - ret = -1; - sbr_set_sk_errno (sk, ENOTTY); - } - - break; - } - - return ret; -} - -/***************************************************************************** -* Prototype : sbr_udp_close -* Description : close -* Input : sbr_socket_t * sk -* Output : None -* Return Value : static int -* Calls : -* Called By : -* -*****************************************************************************/ -static int -sbr_udp_close (sbr_socket_t * sk) -{ - if (sbr_get_fd_share (sk)->lastdata) - { - struct spl_netbuf *buf = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata); - struct spl_pbuf *p = (struct spl_pbuf *) ADDR_SHTOL (buf->p); - sbr_com_free_recv_buf (sk, p); - } - - /* if failed,free it in recycle */ - return sbr_handle_close (sk, 0); -} - -sbr_fdopt udp_fdopt = { - .socket = sbr_udp_socket, - .bind = sbr_udp_bind, - .listen = sbr_udp_listen, - .accept = sbr_udp_accept, - .accept4 = sbr_udp_accept4, - .connect = sbr_udp_connect, - .shutdown = sbr_udp_shutdown, - .getsockname = sbr_udp_getsockname, - .getpeername = sbr_udp_getpeername, - .getsockopt = sbr_udp_getsockopt, - .setsockopt = sbr_udp_setsockopt, - .recvfrom = sbr_udp_recvfrom, - .readv = sbr_udp_readv, - .recvmsg = sbr_udp_recvmsg, - .send = sbr_udp_send, - .sendto = sbr_udp_sendto, - .sendmsg = sbr_udp_sendmsg, - .writev = sbr_udp_writev, - .fcntl = sbr_udp_fcntl, - .ioctl = sbr_udp_ioctl, - .close = sbr_udp_close, - .peak = sbr_com_peak, - .lock_common = sbr_com_lock_common, - .unlock_common = sbr_com_unlock_common, - .fork_parent = sbr_com_fork_parent, - .fork_child = sbr_com_fork_child, - .ep_getevt = stackx_eventpoll_getEvt, - .ep_ctl = stackx_eventpoll_triggle, - .set_close_stat = NULL, -}; |