summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/lwip_stack/lwip_src/socket/stackx_tcp.c')
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_tcp.c1691
1 files changed, 0 insertions, 1691 deletions
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c b/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c
deleted file mode 100644
index a410a4f..0000000
--- a/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c
+++ /dev/null
@@ -1,1691 +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 "nstack_securec.h"
-#include "common_pal_bitwide_adjust.h"
-#include "common_mem_mbuf.h"
-#include "stackx_spl_share.h"
-#include "stackx_err.h"
-#include "stackx_cfg.h"
-#include "spl_opt.h"
-//#include "stackx_tcp_sctl.h"
-#include "stackx_tcp_opt.h"
-//#include "stackx_dfx_api.h"
-#include "stackx_spl_msg.h"
-#ifdef HAL_LIB
-#else
-#include "rte_memcpy.h"
-#endif
-
-static void
-sbr_tcp_init_conn (spl_netconn_t * conn)
-{
- conn->tcp_sndbuf = CONN_TCP_MEM_DEF_LINE;
- conn->conn_pool = sbr_get_conn_pool ();
-}
-
-/* need close after accept failed */
-static void
-sbr_tcp_accept_failed (sbr_socket_t * sk)
-{
- (void) sbr_handle_close (sk, 0);
- sk->stack_obj = NULL;
- sk->sk_obj = NULL;
-}
-
-NSTACK_STATIC int
-sbr_tcp_socket (sbr_socket_t * sk, int domain, int type, int protocol)
-{
- int err = 0;
-
- if (sbr_malloc_conn_for_sk (sk, SPL_NETCONN_TCP) != 0)
- {
- return -1;
- }
-
- sbr_tcp_init_conn (sbr_get_conn (sk));
-
- err = sbr_handle_socket (sk, SPL_NETCONN_TCP, 0);
- if (0 == err)
- {
- /* Prevent automatic window updates, we do this on our own! */
- ss_set_noautorecved_flag (sbr_get_conn (sk), 1);
-
- ss_set_nonblock_flag (sbr_get_conn (sk), (type & O_NONBLOCK));
-
- ss_add_recv_event (sbr_get_conn (sk));
-
- ss_set_send_event (sbr_get_conn (sk), 1);
-
- NSSBR_LOGINF ("add write and read events]fd=%d", sk->fd);
-
- return 0;
- }
- else
- {
- sbr_free_conn_from_sk (sk);
- return err;
- }
-}
-
-NSTACK_STATIC int
-sbr_tcp_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));
-}
-
-NSTACK_STATIC int
-sbr_tcp_listen (sbr_socket_t * sk, int backlog)
-{
- ss_set_is_listen_conn (sbr_get_conn (sk), 1);
- return sbr_handle_listen (sk, backlog);
-}
-
-static inline int
-sbr_tcp_recv_is_timeout (sbr_socket_t * sk, struct timespec *starttm)
-{
- struct timespec currtm;
- i64 timediff_ms, timediff_sec;
- i64 timeout_thr_ms, timeout_thr_sec;
-
- timeout_thr_ms = sbr_get_fd_share (sk)->recv_timeout;
- if (0 == timeout_thr_ms)
- {
- return ERR_OK;
- }
-
- timeout_thr_sec = (i64) (timeout_thr_ms / 1000);
-
- /* Handle system time change side-effects */
- if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &currtm)))
- {
- NSSBR_LOGERR ("Failed to get time, errno = %d", errno);
- }
-
- timediff_sec = currtm.tv_sec - starttm->tv_sec;
- if (timediff_sec >= timeout_thr_sec)
- {
- timediff_ms = currtm.tv_nsec > starttm->tv_nsec ?
- (timediff_sec * 1000) + (currtm.tv_nsec -
- starttm->tv_nsec) /
- USEC_TO_SEC : (timediff_sec * 1000) -
- ((starttm->tv_nsec - currtm.tv_nsec) / USEC_TO_SEC);
-
- /*NOTE: if user configured the timeout as say 0.5 ms, then timediff value
- will be negetive if still 0.5 ms is not elapsed. this is intended and we should
- not typecast to any unsigned type during this below if check */
- if (timediff_ms > timeout_thr_ms)
- {
- sbr_set_sk_errno (sk, ETIMEDOUT);
- return ETIMEDOUT;
- }
- }
-
- return ERR_OK;
-}
-
-static inline int
-sbr_tcp_wait_new_conn (sbr_socket_t * sk, void **new_buf)
-{
- int ret = 0;
- int elem_num;
- u32 timeout_thr_sec;
- struct timespec starttm = { 0, 0 };
- unsigned int retry_count = 0;
- mring_handle ring = NULL;
-
-#define FAST_SLEEP_TIME 10000
-#define SLOW_SLEEP_TIME 500000
-#define FAST_RETRY_COUNT 100
-
- ring = ss_get_recv_ring (sbr_get_conn (sk)); //clear codeDEX warning , CID:24284
- timeout_thr_sec = sbr_get_fd_share (sk)->recv_timeout / 1000;
- if (0 != timeout_thr_sec)
- {
- if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &starttm)))
- {
- NSSBR_LOGERR ("Failed to get time, errno = %d", errno);
- }
- }
-
- while (1)
- {
- if (ss_is_shut_rd (sbr_get_conn (sk)))
- {
- sbr_set_sk_errno (sk, EINVAL);
- ret = EINVAL;
- break;
- }
-
- elem_num = nsfw_mem_ring_dequeue (ring, new_buf);
- if (1 == elem_num)
- {
- break;
- }
- else if (0 == elem_num)
- {
- ret = sbr_tcp_recv_is_timeout (sk, &starttm);
- if (0 != ret)
- {
- break;
- }
-
- /* reduce CPU usage in blocking mode- Begin */
- if (retry_count < FAST_RETRY_COUNT)
- {
- sys_sleep_ns (0, FAST_SLEEP_TIME);
- retry_count++;
- }
- else
- {
- sys_sleep_ns (0, sbr_get_fd_share (sk)->block_polling_time);
- }
-
- continue;
- }
- else
- {
- sbr_set_sk_errno (sk, EINVAL);
- ret = EINVAL;
- break;
- }
- }
-
- return ret;
-}
-
-NSTACK_STATIC inline int
-sbr_tcp_get_sockaddr (sbr_socket_t * sk, struct sockaddr *addr,
- socklen_t * addrlen)
-{
- int ret;
- spl_netconn_t *conn = sbr_get_conn (sk);
-
- ret = (addr
- && addrlen) ? sbr_get_sockaddr_and_len (ss_get_remote_port (conn),
- ss_get_remote_ip (conn),
- addr, addrlen) : 0;
- if (0 != ret)
- {
- sbr_set_sk_io_errno (sk, EINVAL);
- NSSBR_LOGERR ("sbr_tcp_get_sockaddr]fd=%d", sk->fd);
- return -1;
- }
-
- return 0;
-}
-
-static int
-sbr_tcp_accept_socket (sbr_socket_t * sk, sbr_socket_t * new_sk,
- struct sockaddr *addr, socklen_t * addrlen)
-{
- int err;
- spl_netconn_t *newconn = NULL;
-
- err = sbr_tcp_wait_new_conn (sk, (void **) &newconn);
- if (ERR_OK != err)
- {
- return err;
- }
-
- err = sbr_init_conn_for_accept (new_sk, newconn);
- if (ERR_OK != err)
- {
- /*When conn is null, return err; then do not need to free conn */
- return err;
- }
-
- err = sbr_tcp_get_sockaddr (new_sk, addr, addrlen);
- if (ERR_OK != err)
- {
- NSSBR_LOGERR ("sbr_get_sockaddr_and_socklen]ret=%d.", err);
- sbr_tcp_accept_failed (new_sk);
- return -1;
- }
-
- NSSBR_LOGINF
- ("return]listen fd=%d,listen conn=%p,listen private_data=%p,accept fd=%d,accept conn=%p,accept private_data=%p",
- sk->fd, sbr_get_conn (sk), ss_get_private_data (sbr_get_conn (sk)),
- new_sk->fd, sbr_get_conn (new_sk),
- ss_get_private_data (sbr_get_conn (new_sk)));
-
- //ip_addr_info_print(SOCKETS_DEBUG, &sbr_get_conn(new_sk)->share_remote_ip);
-
- /* test_epollCtl_003_001: Accept a conn. Add epoll_ctl with IN event and
- send a msg from peer. The event will be given once epoll_wait is called.
- Now, modify to IN|OUT. Calling epoll_event should return immediately since
- the socket is writable. Currently, returns 0 events.
- This issue is fixed here
- */
-
- /* Prevent automatic window updates, we do this on our own! */
- ss_set_noautorecved_flag (sbr_get_conn (new_sk), 1);
-
- ss_set_send_event (sbr_get_conn (new_sk), 1);
-
- /* don't set conn->last_err: it's only ERR_OK, anyway */
- return ERR_OK;
-}
-
-NSTACK_STATIC int
-sbr_tcp_accept (sbr_socket_t * sk, sbr_socket_t * new_sk,
- struct sockaddr *addr, socklen_t * addrlen)
-{
- int err;
-
- /* If conn is not in listen state then return failure with error code: EINVAL(22) */
- if (!ss_is_listen_state (sbr_get_conn (sk)))
- {
- NSSBR_LOGERR ("fd is not listening for connections]fd=%d,err=%d",
- sk->fd, EINVAL);
- sbr_set_sk_errno (sk, EINVAL);
-
- return -1;
- }
-
- if (ss_is_nonblock_flag (sbr_get_conn (sk))
- && (0 >= ss_get_recv_event (sbr_get_conn (sk))))
- {
- NSSBR_LOGERR ("fd is nonblocking and rcvevent<=0]fd=%d,err=%d", sk->fd,
- EWOULDBLOCK);
- sbr_set_sk_errno (sk, EWOULDBLOCK);
-
- return -1;
- }
-
- err = ss_get_last_errno (sbr_get_conn (sk));
- if (SPL_ERR_IS_FATAL (err))
- {
- /* don't recv on fatal errors: this might block the application task
- waiting on acceptmbox forever! */
- sbr_set_sk_errno (sk, sbr_spl_err_to_errno (err));
-
- return -1;
- }
-
- /* wait for a new connection */
- err = sbr_tcp_accept_socket (sk, new_sk, addr, addrlen);
- if (ERR_OK != err)
- {
- NSSBR_LOGERR ("sbr_tcp_accept_socket failed]fd=%d,err=%d", sk->fd, err);
-
- return -1;
- }
-
- /* Prevent automatic window updates, we do this on our own! */
- ss_sub_recv_event (sbr_get_conn (sk));
-
- sbr_set_sk_errno (sk, ERR_OK);
-
- /* test_epollCtl_003_001: Accept a conn. Add epoll_ctl with IN event and
- send a msg from peer. The event will be given once epoll_wait is called.
- Now, modify to IN|OUT. Calling epoll_event should return immediately since
- the socket is writable. Currently, returns 0 events.
- This issue is fixed here
- */
-
- ss_set_send_event (sbr_get_conn (new_sk), 1);
-
- return new_sk->fd;
-}
-
-NSTACK_STATIC int
-sbr_tcp_accept4 (sbr_socket_t * sk, sbr_socket_t * new_sk,
- struct sockaddr *addr, socklen_t * addrlen, int flags)
-{
- int fd = sbr_tcp_accept (sk, new_sk, addr, addrlen);
-
- if (0 > fd)
- {
- return fd;
- }
-
- if (flags & O_NONBLOCK)
- {
- int opts = new_sk->fdopt->fcntl (new_sk, F_GETFL, 0);
- if (opts < 0)
- {
- NSSBR_LOGERR ("sbr_tcp_fcntl(sock,GETFL)");
- sbr_tcp_accept_failed (new_sk);
- return -1;
- }
-
- opts = opts | O_NONBLOCK;
-
- if (new_sk->fdopt->fcntl (new_sk, F_SETFL, opts) < 0)
-
- {
- NSSBR_LOGERR ("sbr_tcp_fcntl(sock,F_SETFL,opts)");
- sbr_tcp_accept_failed (new_sk);
- return -1;
- }
- }
-
- return new_sk->fd;
-}
-
-NSTACK_STATIC int
-sbr_tcp_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 };
-
- if (sbr_handle_connect (sk, &remote_addr, ntohs (remote_port), &local_addr)
- != 0)
- {
- NSSBR_LOGERR ("fail]fd=%d", sk->fd);
- return -1;
- }
-
- if (ss_is_shut_rd (sbr_get_conn (sk)))
- {
- NSSBR_LOGERR ("shut_rd]fd=%d", sk->fd);
- sbr_set_sk_errno (sk, ECONNRESET);
- return -1;
- }
-
- NSSBR_LOGINF ("succeeded]fd=%d", sk->fd);
- sbr_set_sk_errno (sk, ERR_OK);
-
- return 0;
-}
-
-static u8 netconn_shutdown_opt[] = {
- SPL_NETCONN_SHUT_RD,
- SPL_NETCONN_SHUT_WR,
- SPL_NETCONN_SHUT_RDWR
-};
-
-NSTACK_STATIC int
-sbr_tcp_shutdown (sbr_socket_t * sk, int how)
-{
- err_t err;
-
- if (ss_is_listen_state (sbr_get_conn (sk)))
- {
- return 0;
- }
-
- ss_set_shut_status (sbr_get_conn (sk), how);
-
- err = sbr_handle_shutdown (sk, netconn_shutdown_opt[how]);
-
- return (err == ERR_OK ? 0 : -1);
-}
-
-NSTACK_STATIC int
-sbr_tcp_getsockname (sbr_socket_t * sk, struct sockaddr *name,
- socklen_t * namelen)
-{
-
- NSSBR_LOGINF ("sockname]fd=%d,tcp_state=%d", sk->fd,
- ss_get_tcp_state (sbr_get_conn (sk)));
-
- return sbr_handle_get_name (sk, name, namelen, SBR_GET_SOCK_NAME);
-}
-
-NSTACK_STATIC int
-sbr_tcp_getpeername (sbr_socket_t * sk, struct sockaddr *name,
- socklen_t * namelen)
-{
-
- if (SPL_CLOSED == ss_get_tcp_state (sbr_get_conn (sk)))
- {
- NSSBR_LOGERR ("connection not exist]fd=%d", sk->fd);
- sbr_set_sk_errno (sk, ENOTCONN);
- return -1;
- }
-
- NSSBR_LOGINF ("peername]fd=%d,tcp_state=%d", sk->fd,
- ss_get_tcp_state (sbr_get_conn (sk)));
-
- return sbr_handle_get_name (sk, name, namelen, SBR_GET_PEER_NAME);
-}
-
-static int
-sbr_getsockopt_ipproto_tcp (int optname, void *optval, socklen_t optlen)
-{
- int err = ERR_OK;
-
- switch (optname)
- {
- case SPL_TCP_NODELAY:
- break;
- case SPL_TCP_KEEPIDLE:
- case SPL_TCP_KEEPINTVL:
- case SPL_TCP_KEEPCNT:
- case SPL_TCP_INFO:
- break;
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-NSTACK_STATIC int inline
-sbr_tcp_set_sockopt_err (sbr_socket_t * sk, int err)
-{
- if (ENOPROTOOPT == err)
- {
- return 0;
- }
- else
- {
- sbr_set_sk_errno (sk, err);
- return -1;
- }
-}
-
-NSTACK_STATIC int inline
-sbr_tcp_get_sockopt_err (sbr_socket_t * sk, int err)
-{
- sbr_set_sk_errno (sk, err);
- return -1;
-}
-
-NSTACK_STATIC int
-sbr_tcp_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 IPPROTO_TCP:
- err = sbr_getsockopt_ipproto_tcp (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
- ("tcp 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 (0 != err)
- {
- NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level,
- optname, err);
- /* for option not support ,getsockopt() should return fail */
- return sbr_tcp_get_sockopt_err (sk, err);
- }
-
- return sbr_handle_getsockopt (sk, level, optname, optval, optlen);
-}
-
-int
-sbr_setsockopt_ipproto_tcp (int optname, socklen_t optlen)
-{
- int err = 0;
-
- if (optlen < sizeof (int))
- {
- return EINVAL;
- }
-
- switch (optname)
- {
- case SPL_TCP_NODELAY:
- case SPL_TCP_KEEPIDLE:
- case SPL_TCP_KEEPINTVL:
- case SPL_TCP_KEEPCNT:
- break;
- default:
- err = ENOPROTOOPT;
- break;
- }
-
- return err;
-}
-
-NSTACK_STATIC int
-sbr_tcp_setsockopt (sbr_socket_t * sk, int level, int optname,
- const void *optval, socklen_t optlen)
-{
- int err = 0;
-
- switch (level)
- {
- case SOL_SOCKET:
- err =
- sbr_setsockopt_sol_socket (sk, optname, optval, optlen,
- SPL_NETCONN_TCP);
- break;
- case IPPROTO_IP:
- err =
- sbr_setsockopt_ipproto_ip (optname, optval, optlen, SPL_NETCONN_TCP);
- break;
- case IPPROTO_TCP:
- err = sbr_setsockopt_ipproto_tcp (optname, optlen);
- 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
- ("tcp 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 (0 != err)
- {
- NSSBR_LOGERR ("fail]fd=%d,level=%d,optname=%d,err=%d", sk->fd, level,
- optname, err);
-
- return sbr_tcp_set_sockopt_err (sk, err);
- }
-
- return sbr_handle_setsockopt (sk, level, optname, optval, optlen);
-}
-
-static inline u16
-sbr_tcp_mbuf_count (struct spl_pbuf *p)
-{
- u16 count = 0;
- struct spl_pbuf *buf = p;
- struct common_mem_mbuf *mbuf;
-
- while (buf)
- {
- mbuf =
- (struct common_mem_mbuf *) ((char *) buf -
- sizeof (struct common_mem_mbuf));
- while (mbuf)
- {
- count++;
-#ifdef HAL_LIB
-#else
- mbuf = mbuf->next;
-#endif
- }
-
- buf = (struct spl_pbuf *) ADDR_SHTOL (buf->next_a);
- }
-
- return count;
-}
-
-static inline void
-sbr_tcp_free_recvbuf (sbr_socket_t * sk, struct spl_pbuf *p)
-{
- int len;
-
- if (ss_is_noautorecved_flag (sbr_get_conn (sk)))
- {
- len = sbr_tcp_mbuf_count (p);
- sbr_handle_tcp_recv (sk, len, p);
- }
-}
-
-static inline void
-sbr_tcp_recv_no_peak (sbr_socket_t * sk, struct spl_pbuf *buf, u32 buflen,
- u32 copylen)
-{
- if ((buflen - copylen) > 0)
- {
- sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (buf);
- sbr_get_fd_share (sk)->lastoffset += copylen;
- }
- else
- {
- sbr_get_fd_share (sk)->lastdata = 0;
- sbr_get_fd_share (sk)->lastoffset = 0;
- sbr_tcp_free_recvbuf (sk, buf);
- }
-}
-
-static inline int
-sbr_tcp_recv_from_ring (sbr_socket_t * sk, struct spl_pbuf **buf, i32 timeout)
-{
- int err;
- spl_netconn_t *conn = sbr_get_conn (sk);
-
- err = ss_get_last_errno (conn);
- if (SPL_ERR_IS_FATAL (err))
- {
- /* don't recv on fatal errors: this might block the application task
- waiting on recvmbox forever! */
-
- /* @todo: this does not allow us to fetch data that has been put into recvmbox
- before the fatal error occurred - is that a problem? */
- NSSBR_LOGDBG ("last err when recv:]=%d", err);
- if (ERR_CLSD != err)
- {
- sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err));
- return -1;
- }
- }
-
- *buf = NULL;
- if (0 != sbr_dequeue_buf (sk, (void **) buf, timeout))
- {
- return -1;
- }
-
- ss_sub_recv_avail (sbr_get_conn (sk), (*buf)->tot_len);
-
- ss_sub_recv_event (sbr_get_conn (sk));
-
- return 0;
-}
-
-static inline int
-sbr_tcp_recv_state_check (sbr_socket_t * sk)
-{
-
- spl_tcp_state_t state = ss_get_tcp_state (sbr_get_conn (sk));
-
- NSSBR_LOGDBG ("tcp state when recv:]=%d", state);
-
- //close_wait state also can recive data
- //no connect cannot recive data
- if (SPL_ESTABLISHED > state)
- {
- if (SPL_SHUT_WR != ss_get_shut_status (sbr_get_conn (sk)))
- {
- /* after all data retrnasmission, connection is active */
- /* patch solution as last_err is not maintained properly */
- if ((SPL_CLOSED == state)
- && (ERR_TIMEOUT == ss_get_last_errno (sbr_get_conn (sk))))
- {
- sbr_set_sk_io_errno (sk, ETIMEDOUT);
- }
- else if ((SPL_CLOSED == state)
- && (ERR_RST == ss_get_last_errno (sbr_get_conn (sk))))
- {
- sbr_set_sk_io_errno (sk, ECONNRESET);
- }
- else
- {
- sbr_set_sk_io_errno (sk, ENOTCONN);
- }
-
- return -1;
- }
- }
-
- return 0;
-}
-
-NSTACK_STATIC int
-sbr_tcp_recvfrom (sbr_socket_t * sk, void *mem, size_t len, int flags,
- struct sockaddr *from, socklen_t * fromlen)
-{
- struct spl_pbuf *p;
- u32 buflen;
- u32 copylen;
- u32 off = 0;
- u8 done = 0;
- int para_len = len;
- int retval = 0;
-
- sbr_com_lock_recv (sk);
- NSSOC_LOGINF ("recv start, fd = %d last data %p flags to be set %d", sk->fd,
- ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata), MSG_DONTWAIT);
-
- if (0 != sbr_tcp_recv_state_check (sk))
- {
- retval = -1;
- goto sbr_tcp_recvfrom_exit;
- }
-
- do
- {
- if (sbr_get_fd_share (sk)->lastdata)
- {
- p = ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata);
- }
- else
- {
- if ((flags & MSG_DONTWAIT)
- || ss_is_nonblock_flag (sbr_get_conn (sk)))
- {
- NSSOC_LOGINF ("call ss_get_recv_event");
- if (0 >= ss_get_recv_event (sbr_get_conn (sk)))
- {
- NSSOC_LOGINF ("no recv event]fd=%d", sk->fd);
- sbr_set_sk_io_errno (sk, EWOULDBLOCK);
- retval = -1;
- goto sbr_tcp_recvfrom_exit;
- }
- }
-
- if (0 !=
- sbr_tcp_recv_from_ring (sk, &p,
- sbr_get_fd_share (sk)->recv_timeout))
- {
- /* already received data, return that */
- if (off > 0)
- {
- sbr_set_sk_io_errno (sk, ERR_OK);
- retval = off;
- goto sbr_tcp_recvfrom_exit;
- }
-
- /* we tell the user the connection is closed by returning zero */
- if (sbr_get_sk_errno (sk) == ENOTCONN)
- {
- retval = 0;
- goto sbr_tcp_recvfrom_exit;
- }
-
- retval = -1;
- goto sbr_tcp_recvfrom_exit;
- }
-
- sbr_get_fd_share (sk)->lastdata = (void *) ADDR_LTOSH (p);
- }
-
- buflen = p->tot_len - sbr_get_fd_share (sk)->lastoffset;
- copylen = len > buflen ? buflen : len;
-
- if ((copylen > 0)
- && 0 == spl_pbuf_copy_partial (p, (u8 *) mem + off, copylen,
- sbr_get_fd_share (sk)->lastoffset))
- {
- NSSBR_LOGERR ("copy failed]fd=%d", sk->fd);
- sbr_set_sk_io_errno (sk, EFAULT);
- retval = -1;
- goto sbr_tcp_recvfrom_exit;
- }
-
- off += copylen;
-
- len -= copylen;
-
- if ((len == 0) || (ss_get_recv_event (sbr_get_conn (sk)) <= 0)
- || ((flags & MSG_PEEK) != 0))
- {
- if ((off >= sbr_get_fd_share (sk)->rcvlowat)
- || (para_len <= sbr_get_fd_share (sk)->rcvlowat))
- {
- done = 1;
- }
- }
-
- if (done)
- {
- if (sbr_tcp_get_sockaddr (sk, from, fromlen) != 0)
- {
- retval = -1;
- goto sbr_tcp_recvfrom_exit;
- }
- }
-
- /* If this is a TCP socket, check if there is data left in the buffer,
- If so, it should be saved in the sock structure for next time around. */
- if (!(flags & MSG_PEEK))
- {
- sbr_tcp_recv_no_peak (sk, p, buflen, copylen);
- }
- }
- while (!done);
-
- retval = off;
-
- NSSOC_LOGINF ("recv done, fd = %d last data %p", sk->fd);
-sbr_tcp_recvfrom_exit:
-
- NSSOC_LOGINF ("recv exit, fd = %d last data %p", sk->fd);
- sbr_com_unlock_recv (sk);
- return retval;
-}
-
-/*****************************************************************************
-* Prototype : sbr_tcp_recvdata
-* Description : recvdata
-* Input : sbr_socket_t* sk
-* const struct iovec* iov
-* int iovcnt
-* int flags
-* Output : None
-* Return Value : static inline int
-* Calls :
-* Called By :
-*
-*****************************************************************************/
-static inline int
-sbr_tcp_recvdata (sbr_socket_t * sk, const struct iovec *iov, int iovcnt)
-{
- int max = SBR_MAX_INTEGER;
- int len = 0;
- int ret = 0;
- int i = 0;
-
- do
- {
- len += ret;
-
- if (!iov[i].iov_base || (0 == iov[i].iov_len))
- {
- ret = 0;
- continue;
- }
-
- ret = sbr_tcp_recvfrom (sk, (char *) iov[i].iov_base, iov[i].iov_len, 0,
- NULL, NULL);
- }
- while ((ret == (int) iov[i].iov_len) && (iovcnt > (++i))
- && (max - len - ret > (int) iov[i].iov_len));
-
- if (len == 0)
- {
- return ret;
- }
- else
- {
- return (ret == -1 ? len : len + ret);
- }
-}
-
-/*****************************************************************************
-* Prototype : sbr_tcp_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_tcp_readv (sbr_socket_t * sk, const struct iovec *iov, int iovcnt)
-{
- return sbr_tcp_recvdata (sk, iov, iovcnt);
-}
-
-/*****************************************************************************
-* Prototype : sbr_tcp_recvmsg
-* Description : recvmsg,unsupport flags
-* Input : sbr_socket_t* sk
-* struct msghdr* msg
-* int flags
-* Output : None
-* Return Value : static int
-* Calls :
-* Called By :
-*
-*****************************************************************************/
-static int
-sbr_tcp_recvmsg (sbr_socket_t * sk, struct msghdr *msg, int flags)
-{
- if (sbr_tcp_get_sockaddr
- (sk, (struct sockaddr *) msg->msg_name, &msg->msg_namelen) != 0)
- {
- return -1;
- }
-
- return sbr_tcp_recvdata (sk, msg->msg_iov, msg->msg_iovlen);
-}
-
-static int
-sbr_tcp_send_is_timeout (sbr_socket_t * sk, struct timespec *starttm)
-{
- struct timespec currtm;
- i64 timediff_ms, timediff_sec;
- i64 timeout_thr_ms, timeout_thr_sec;
-
- timeout_thr_ms = sbr_get_fd_share (sk)->send_timeout;
- if (0 == timeout_thr_ms)
- {
- return 0;
- }
-
- /* it is possible that starttm don't be inited,
- if send_timeout is change when this write function is running */
- timeout_thr_sec = (timeout_thr_ms + 240) >> 10;
-
- /* Handle system time change side-effects */
- if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &currtm)))
- {
- NSSBR_LOGERR ("Failed to get time, errno = %d", errno);
- }
-
- timediff_sec = currtm.tv_sec - starttm->tv_sec;
- if (timediff_sec >= timeout_thr_sec)
- {
- timediff_ms = currtm.tv_nsec > starttm->tv_nsec ?
- (timediff_sec * 1000) + (currtm.tv_nsec -
- starttm->tv_nsec) /
- USEC_TO_SEC : (timediff_sec * 1000) -
- ((starttm->tv_nsec - currtm.tv_nsec) / USEC_TO_SEC);
-
- /*NOTE: if user configured the timeout as say 0.5 ms, then timediff value
- will be negetive if still 0.5 ms is not elapsed. this is intended and we should
- not typecast to any unsigned type during this below if check */
- if (timediff_ms > timeout_thr_ms)
- {
- return 1;
- }
- }
-
- return 0;
-}
-
-static inline int
-sbr_tcp_write_is_wait (sbr_socket_t * sk, struct timespec *starttm,
- int noneblockFlg)
-{
- if (noneblockFlg || sbr_tcp_send_is_timeout (sk, starttm))
- {
- return 0;
- }
- else
- {
- return 1;
- }
-}
-
-static struct spl_pbuf *
-sbr_tcp_write_alloc_buf (sbr_socket_t * sk, size_t seglen, u8 api_flag,
- struct timespec *starttm, u8 * errno_flag)
-{
- spl_netconn_t *conn = sbr_get_conn (sk);
-
- struct spl_pbuf *curr_buf = NULL;
- size_t head_len = SPL_TCP_HLEN + SPL_PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN;
- int noneblockFlg = (api_flag & SPL_NETCONN_DONTBLOCK)
- || ss_is_nonblock_flag (sbr_get_conn (sk));
-
- do
- {
- /* When packages are lost more than TCP_MAXRTX times,
- * conn will be closed and pcb will be removed. */
- if (ss_get_tcp_state (conn) == SPL_CLOSED)
- {
- NSSBR_LOGERR ("pcb SPL_CLOSED]conn=%p", conn);
- sbr_set_sk_io_errno (sk, ECONNABORTED);
- /* Must set errno_flag when set errno, to avoid errnno overwritten by sbr_tcp_write */
- *errno_flag = 1;
- return NULL;
- }
-
- curr_buf = sbr_malloc_tx_pbuf (seglen + head_len, head_len);
- if (NULL == curr_buf)
- {
- if (!sbr_tcp_write_is_wait (sk, starttm, noneblockFlg))
- {
- return NULL;
- }
-
- int err = ss_get_last_errno (sbr_get_conn (sk));
- if (SPL_ERR_IS_FATAL (err))
- {
- NSSBR_LOGERR ("connection fatal error!err=%d", err);
- sbr_set_sk_io_errno (sk, sbr_spl_err_to_errno (err));
- *errno_flag = 1;
- return NULL;
- }
-
- sched_yield ();
- }
- }
- while (curr_buf == NULL);
-
- return curr_buf;
-}
-
-static inline void
-sbr_tcp_write_rel_buf (sbr_socket_t * sk, struct spl_pbuf *buf,
- u32 thread_index)
-{
- if (buf != NULL)
- {
- sbr_handle_free_send_buf (sk, buf);
- }
-}
-
-static inline int
-sbr_tcp_write_fill_buf (const void *data, size_t * pos,
- struct spl_pbuf *seg_buf, size_t seglen,
- size_t optlen)
-{
- size_t start = *pos;
- size_t copy = seglen;
- struct spl_pbuf *first = seg_buf;
-
- while ((0 < copy) && (NULL != first))
- {
- char *dst_ptr = PTR_SHTOL (char *, first->payload_a) + optlen;
-
- if (NULL ==
- common_memcpy (dst_ptr, (u8_t *) data + start, first->len - optlen))
- {
- NSSBR_LOGERR ("common_memcpy error]dst=%p,src=%p,len=%u",
- dst_ptr, (u8_t *) data + start, first->len);
- return -1;
- }
-
- start += (first->len - optlen);
- copy -= (first->len - optlen);
- first = ADDR_SHTOL (first->next_a);
- }
-
- (*pos) = start;
-
- return 0;
-}
-
-static inline int
-sbr_tcp_writev_fill_buf (const struct iovec *iov, size_t * iov_pos,
- int *iov_var, size_t * pos, struct spl_pbuf *seg_buf,
- size_t seglen, size_t optlen)
-{
- size_t valid_copy_len;
- size_t iov_data_left;
-
- size_t copy = seglen;
- size_t start = *pos;
- size_t current_iov_pos = *iov_pos;
- int current_iov_var = *iov_var;
-
- u32 pbuf_offset = optlen;
- u32 pbuf_data_len;
- struct spl_pbuf *first = seg_buf;
-
- while ((0 < copy) && (NULL != first))
- {
- iov_data_left = iov[current_iov_var].iov_len - current_iov_pos;
- if (seglen == copy)
- {
- pbuf_offset = optlen;
- }
-
- pbuf_data_len = first->len - pbuf_offset;
- valid_copy_len =
- (iov_data_left > pbuf_data_len ? pbuf_data_len : iov_data_left);
- if (NULL ==
- common_memcpy ((char *) ADDR_SHTOL (first->payload_a) + pbuf_offset,
- (u8_t *) iov[current_iov_var].iov_base +
- current_iov_pos, valid_copy_len))
- {
- NSSBR_LOGERR
- ("common_memcpy error]current_iov_var=%d, dst=%p,src=%p,len=%zu",
- current_iov_var,
- (char *) ADDR_SHTOL (first->payload_a) + pbuf_offset,
- (u8_t *) iov[current_iov_var].iov_base + current_iov_pos,
- valid_copy_len);
- return -1;
- }
-
- start += valid_copy_len;
- copy -= valid_copy_len;
-
- if (iov_data_left == pbuf_data_len)
- {
- first = PTR_SHTOL (struct spl_pbuf *, first->next_a);
- pbuf_offset = optlen; //+= valid_copy_len;
- current_iov_var++;
- current_iov_pos = 0;
- }
- else if (iov_data_left > pbuf_data_len)
- {
- first = PTR_SHTOL (struct spl_pbuf *, first->next_a);
- pbuf_offset = optlen; //+= valid_copy_len;
- current_iov_pos += valid_copy_len;
- }
- else
- {
- pbuf_offset += valid_copy_len;
-
- current_iov_var++;
- current_iov_pos = 0;
- }
- }
-
- *iov_pos = current_iov_pos;
- *iov_var = current_iov_var;
- *pos = start;
-
- return 0;
-}
-
-static inline void
-sbr_tcp_write_add_buf_to_list (struct spl_pbuf **p_head,
- struct spl_pbuf **p_tail,
- struct spl_pbuf *seg_buf, size_t seglen,
- size_t optlen)
-{
- seg_buf->len = seglen + optlen;
- seg_buf->tot_len = seglen + optlen;
- seg_buf->next_a = 0;
-
- /*put seg_buf after p_head */
- if (NULL == (*p_head))
- {
- (*p_head) = seg_buf;
- (*p_tail) = seg_buf;
- }
- else
- {
- (*p_tail)->next_a = ADDR_LTOSH (seg_buf);
- (*p_tail) = seg_buf;
- }
-}
-
-NSTACK_STATIC int
-sbr_tcp_write (sbr_socket_t * sk, const void *data, size_t size, u8 api_flag,
- size_t * written)
-{
- err_t err = -1;
- size_t pos = 0, left, seglen;
- u32 pbuf_seg_cnt = 0;
- u32 thread_index = 0;
- struct spl_pbuf *seg_buf = NULL;
- struct spl_pbuf *p_head = NULL;
- struct spl_pbuf *p_tail = p_head;
- struct spl_netconn *conn = sbr_get_conn (sk);
- u32 mss = ss_get_mss (sbr_get_conn (sk));
-
- if (0 == size)
- {
- NSSBR_LOGERR ("fd=%d,size=%u", sk->fd, (u32) size);
- return 0;
- }
-
- struct timespec ts;
- if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &ts)))
- {
- NSSBR_LOGERR ("Failed to get time, errno = %d", errno);
- }
-
- while (pos < size)
- {
- left = size - pos;
- seglen = left > mss ? mss : left;
- u8 errno_set = 0;
- seg_buf =
- sbr_tcp_write_alloc_buf (sk, seglen, api_flag, &ts, &errno_set);
- if (NULL == seg_buf)
- {
- NSSBR_LOGINF ("sbr_tcp_write_alloc_buf failed......");
- if (NULL != p_head)
- {
- err = sbr_handle_tcp_send (sk, size, p_head, api_flag);
- if (ERR_OK != err)
- {
- NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err);
- goto err_ref_buf;
- }
- }
-
- if (0 == pos)
- {
- /* If errno is already set in sbr_tcp_write_alloc_buf, do not overwrite here */
- if (!errno_set)
- {
- sbr_set_sk_io_errno (sk, EWOULDBLOCK);
- }
- return -1;
- }
-
- NSSBR_LOGDBG ("sent size %zu", pos);
- *written = pos;
-
- return ERR_OK;
- }
-
- if (0 != sbr_tcp_write_fill_buf (data, &pos, seg_buf, seglen, 0))
- {
- sbr_set_sk_io_errno (sk, EFAULT);
- NSSBR_LOGERR ("sbr_tcp_write_fill_buf error]");
- goto err_ref_buf;
- }
-
- sbr_tcp_write_add_buf_to_list (&p_head, &p_tail, seg_buf, seglen, 0);
-
- ++pbuf_seg_cnt;
- if (p_head
- && ((SPL_TCP_SEND_MAX_SEG_PER_MSG <= pbuf_seg_cnt)
- || (pos >= size)))
- {
- pbuf_seg_cnt = 0;
- err = sbr_handle_tcp_send (sk, size, p_head, api_flag);
- if (ERR_OK != err)
- {
- NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err);
- goto err_ref_buf;
- }
-
- p_head = NULL;
- }
- }
-
- *written = size;
-
- (void) conn;
- return ERR_OK;
-
-err_ref_buf:
- sbr_tcp_write_rel_buf (sk, p_head, thread_index);
- (void) conn;
- return -1;
-}
-
-NSTACK_STATIC int
-sbr_tcp_writev (sbr_socket_t * sk, const struct iovec *iov, int iovcnt)
-{
- err_t err = -1;
- int idx = 0;
- size_t pos = 0, left, seglen, optlen = 0;
- u32 pbuf_seg_cnt = 0;
- u32 thread_index = 0;
- size_t size = 0;
- size_t iov_pos = 0;
- int iov_var = 0;
- struct spl_pbuf *seg_buf = NULL;
- struct spl_pbuf *p_head = NULL;
- struct spl_pbuf *p_tail = p_head;
- struct spl_netconn *conn = sbr_get_conn (sk);
- u32 mss = ss_get_mss (sbr_get_conn (sk));
-
- if (mss <= optlen)
- {
- NSSBR_LOGERR ("mss invalid]mss=%u,optlen=%zu,fd=%d", mss, optlen,
- sk->fd);
- sbr_set_sk_io_errno (sk, EINVAL);
- return -1;
- }
-
- /* mss dose't include the tcp options length */
- mss -= optlen;
-
- while (idx < iovcnt)
- {
- if (SBR_MAX_INTEGER - iov[idx].iov_len <= size)
- {
- size = SBR_MAX_INTEGER;
- break;
- }
-
- size += iov[idx].iov_len;
- idx++;
- }
-
- struct timespec starttm;
- if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &starttm)))
- {
- NSSBR_LOGERR ("Failed to get time, errno = %d", errno);
- }
-
- while (pos < size)
- {
- left = size - pos;
-
- seglen = left > mss ? mss : left;
- u8 errno_set = 0;
- seg_buf =
- sbr_tcp_write_alloc_buf (sk, seglen + optlen, SPL_NETCONN_COPY,
- &starttm, &errno_set);
- if (NULL == seg_buf)
- {
- if (NULL != p_head)
- {
- err = sbr_handle_tcp_send (sk, size, p_head, SPL_NETCONN_COPY);
- /*If errno is already set in sbr_tcp_write_alloc_buf, do not overwrite here */
- if (err != ERR_OK)
- {
- NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err);
- goto err_ref_buf;
- }
- }
-
- /* [Start]
- 1)Set SO_SNDTIMEO to 10
- 2)Send a msg of larger buff size.and let the timeout happen for send (dont receive at peer side.)
- 3)iRet will be 0 and errno received will be 11 (EAGAIN).
-
- Above issue is fixed.
- */
- if (0 == pos)
- {
- if (!errno_set)
- {
- sbr_set_sk_io_errno (sk, EWOULDBLOCK);
- }
- return -1;
- }
- /* [End] */
-
- NSSBR_LOGDBG ("sent size %zu", pos);
-
- return pos;
- }
-
- if (0 !=
- sbr_tcp_writev_fill_buf (iov, &iov_pos, &iov_var, &pos, seg_buf,
- seglen, optlen))
- {
- sbr_set_sk_io_errno (sk, EFAULT);
- NSSBR_LOGERR ("sbr_tcp_writev_fill_buf error]");
- goto err_ref_buf;
- }
-
- sbr_tcp_write_add_buf_to_list (&p_head, &p_tail, seg_buf, seglen,
- optlen);
-
- /* @todo: for non-blocking write, check if 'size' would ever fit into
- snd_queue or snd_buf */
- ++pbuf_seg_cnt;
- if (p_head
- && ((SPL_TCP_SEND_MAX_SEG_PER_MSG <= pbuf_seg_cnt)
- || (pos >= size)))
- {
- pbuf_seg_cnt = 0;
- err = sbr_handle_tcp_send (sk, size, p_head, SPL_NETCONN_COPY);
- if (ERR_OK != err)
- {
- NSSBR_LOGERR ("sbr_handle_tcp_send error]err(%d)", err);
- goto err_ref_buf;
- }
-
- p_head = NULL;
- }
- }
- (void) conn;
- return size;
-
-err_ref_buf:
- sbr_tcp_write_rel_buf (sk, p_head, thread_index);
- (void) conn;
- return -1;
-}
-
-NSTACK_STATIC int
-sbr_tcp_sendto (sbr_socket_t * sk, const void *data, size_t size, int flags,
- const struct sockaddr *to, socklen_t tolen)
-{
- return sk->fdopt->send (sk, data, size, flags);
-}
-
-static inline int
-sbr_tcp_send_state_check (sbr_socket_t * sk)
-{
- if ((SPL_SHUT_WR == ss_get_shut_status (sbr_get_conn (sk)))
- || (SPL_SHUT_RDWR == ss_get_shut_status (sbr_get_conn (sk))))
- {
- sbr_set_sk_io_errno (sk, EPIPE);
- return -1;
- }
-
- spl_tcp_state_t state = ss_get_tcp_state (sbr_get_conn (sk));
- if ((SPL_ESTABLISHED != state) && (SPL_CLOSE_WAIT != state))
- {
- /* after all data retrnasmission, connection is active */
- /* patch solution as last_err is not maintained properly */
- if ((SPL_CLOSED == state)
- && (ERR_TIMEOUT == ss_get_last_errno (sbr_get_conn (sk))))
- {
- sbr_set_sk_io_errno (sk, ETIMEDOUT);
- }
- else if ((SPL_CLOSED == state)
- && (ERR_RST == ss_get_last_errno (sbr_get_conn (sk))))
- {
- sbr_set_sk_io_errno (sk, ECONNRESET);
- }
- else
- {
- sbr_set_sk_io_errno (sk, EPIPE);
- }
-
- return -1;
- }
-
- return 0;
-}
-
-NSTACK_STATIC int
-sbr_tcp_send (sbr_socket_t * sk, const void *data, size_t size, int flags)
-{
- int err;
- size_t written = 0;
- u8 write_flags;
-
- if (0 != sbr_tcp_send_state_check (sk))
- {
- NSSBR_LOGDBG ("tcp state not correct]fd=%d, err=%d", sk->fd,
- sbr_get_sk_errno (sk));
- return -1;
- }
-
- write_flags = SPL_NETCONN_COPY |
- ((flags & MSG_MORE) ? SPL_NETCONN_MORE : 0) |
- ((flags & MSG_DONTWAIT) ? SPL_NETCONN_DONTBLOCK : 0);
-
- NSSBR_LOGINF ("Sbr tcp write start");
- err = sbr_tcp_write (sk, data, size, write_flags, &written);
- NSSBR_LOGINF ("Sbr tcp write end written %d", written);
-
- return (err == ERR_OK ? written : -1);
-}
-
-NSTACK_STATIC int
-sbr_tcp_sendmsg (sbr_socket_t * sk, const struct msghdr *pmsg, int flags)
-{
- if (0 != sbr_tcp_send_state_check (sk))
- {
- NSSBR_LOGDBG ("tcp state not correct]fd=%d, err=%d", sk->fd,
- sbr_get_sk_errno (sk));
- return -1;
- }
-
- return sbr_tcp_writev (sk, pmsg->msg_iov, pmsg->msg_iovlen);
-}
-
-NSTACK_STATIC int
-sbr_tcp_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;
-}
-
-NSTACK_STATIC int
-sbr_tcp_ioctl (sbr_socket_t * sk, unsigned long cmd, void *arg)
-{
- int ret = 0;
- int recv_avail;
-
- switch (cmd)
- {
- case FIONREAD:
- {
- if (ss_is_listen_state (sbr_get_conn (sk)))
- {
- ret = -1;
- sbr_set_sk_errno (sk, EINVAL);
- break;
- }
-
- recv_avail = ss_get_recv_avail (sbr_get_conn (sk));
- *((u32 *) arg) = recv_avail >= 0 ? recv_avail : 0;
- if (sbr_get_fd_share (sk)->lastdata)
- {
- struct spl_pbuf *buf =
- ADDR_SHTOL (sbr_get_fd_share (sk)->lastdata);
- *((u32 *) arg) +=
- (buf->tot_len - sbr_get_fd_share (sk)->lastoffset);
- }
- }
-
- 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;
-}
-
-NSTACK_STATIC int
-sbr_tcp_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_tcp_free_recvbuf (sk, p);
- }
-
- return sbr_handle_close (sk, 0);
-}
-
-sbr_fdopt tcp_fdopt = {
- .socket = sbr_tcp_socket,
- .bind = sbr_tcp_bind,
- .listen = sbr_tcp_listen,
- .accept = sbr_tcp_accept,
- .accept4 = sbr_tcp_accept4,
- .connect = sbr_tcp_connect,
- .shutdown = sbr_tcp_shutdown,
- .getsockname = sbr_tcp_getsockname,
- .getpeername = sbr_tcp_getpeername,
- .getsockopt = sbr_tcp_getsockopt,
- .setsockopt = sbr_tcp_setsockopt,
- .recvfrom = sbr_tcp_recvfrom,
- .readv = sbr_tcp_readv,
- .recvmsg = sbr_tcp_recvmsg,
- .send = sbr_tcp_send,
- .sendto = sbr_tcp_sendto,
- .sendmsg = sbr_tcp_sendmsg,
- .writev = sbr_tcp_writev,
- .fcntl = sbr_tcp_fcntl,
- .ioctl = sbr_tcp_ioctl,
- .close = sbr_tcp_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,
-};