summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/src/sbr/sbr_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/lwip_stack/src/sbr/sbr_socket.c')
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_socket.c1324
1 files changed, 1324 insertions, 0 deletions
diff --git a/stacks/lwip_stack/src/sbr/sbr_socket.c b/stacks/lwip_stack/src/sbr/sbr_socket.c
new file mode 100644
index 0000000..27f3ad1
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_socket.c
@@ -0,0 +1,1324 @@
+/*
+*
+* 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 <dlfcn.h>
+#include "sbr_protocol_api.h"
+#include "sbr_res_mgr.h"
+#include "nstack_log.h"
+#include "nsfw_shmem_mdesc.h"
+#include "nsfw_nshmem_mdesc.h"
+#include "nstack_callback_ops.h"
+#include "nstack_rd_data.h"
+
+#define SBR_INTERCEPT(ret, name, args) ret sbr_ ## name args
+#define CALL_SBR_INTERCEPT(name, args) sbr_ ## name args
+#define GET_SBR_INTERCEPT(name) sbr_ ## name
+
+void *lwip_rd_table = NULL;
+extern nsfw_ring_ops
+ g_ring_ops_arry_lwip[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX];
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : create socket
+* Input : int
+* socket
+* (int domain
+* int type
+* int protocol)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, socket, (int domain, int type, int protocol))
+{
+ NSSBR_LOGDBG("socket]domain=%d,type=%d,protocol=%d", domain, type,
+ protocol);
+ sbr_fdopt *fdopt = sbr_get_fdopt(domain, type, protocol);
+
+ if (!fdopt)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_malloc_sk();
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt = fdopt;
+
+ int ret = sk->fdopt->socket(sk, domain, type, protocol);
+
+ if (ret != 0)
+ {
+ sbr_free_sk(sk);
+ return ret;
+ }
+
+ return sk->fd;
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_addr
+* Description : check addr
+* Input : int s
+* struct sockaddr * addr
+* socklen_t * addrlen
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int
+sbr_check_addr(int s, struct sockaddr *addr, socklen_t * addrlen)
+{
+ if (addr)
+ {
+ if (!addrlen)
+ {
+ NSSBR_LOGERR("addrlen is null]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (0 > (int) (*addrlen))
+ {
+ NSSBR_LOGERR("addrlen is negative]fd=%d,addrlen=%d", s, *addrlen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : accept4
+* Input : int
+* accept4
+* (int s
+* struct sockaddr * addr
+* socklen_t * addrlen
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, accept4,
+ (int s, struct sockaddr * addr, socklen_t * addrlen, int flags))
+{
+ NSSBR_LOGDBG("accept4]fd=%d,addr=%p,addrlen=%p,flags=%d", s, addr,
+ addrlen, flags);
+ int ret = sbr_check_addr(s, addr, addrlen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *new_sk = sbr_malloc_sk();
+ if (!new_sk)
+ {
+ return -1;
+ }
+
+ new_sk->fdopt = sk->fdopt;
+
+ ret = sk->fdopt->accept4(sk, new_sk, addr, addrlen, flags);
+ if (-1 == ret)
+ {
+ sbr_free_sk(new_sk);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : accept
+* Input : int
+* accept
+* (int s
+* struct sockaddr * addr
+* socklen_t * addrlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, accept,
+ (int s, struct sockaddr * addr, socklen_t * addrlen))
+{
+ NSSBR_LOGDBG("accept]fd=%d,addr=%p,addrlen=%p", s, addr, addrlen);
+ int ret = sbr_check_addr(s, addr, addrlen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *new_sk = sbr_malloc_sk();
+ if (!new_sk)
+ {
+ return -1;
+ }
+
+ new_sk->fdopt = sk->fdopt;
+
+ ret = sk->fdopt->accept(sk, new_sk, addr, addrlen);
+ if (-1 == ret)
+ {
+ sbr_free_sk(new_sk);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : bind
+* Input : int
+* bind
+* (int s
+* const struct sockaddr * name
+* socklen_t namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, bind,
+ (int s, const struct sockaddr * name, socklen_t namelen))
+{
+ NSSBR_LOGDBG("bind]fd=%d,name=%p,namelen=%d", s, name, namelen);
+ if (!name)
+ {
+ NSSBR_LOGERR("name is not ok]fd=%d,name=%p", s, name);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if ((name->sa_family) != AF_INET)
+ {
+ NSSBR_LOGERR("domain is not AF_INET]fd=%d,name->sa_family=%u", s,
+ name->sa_family);
+ sbr_set_errno(EAFNOSUPPORT);
+ return -1;
+ }
+
+ if (namelen != sizeof(struct sockaddr_in))
+ {
+ NSSBR_LOGERR("namelen is invalid]fd=%d,namelen=%d", s, namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->bind(sk, name, namelen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : listen
+* Input : int
+* listen
+* (int s
+* int backlog)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, listen, (int s, int backlog))
+{
+ NSSBR_LOGDBG("listen]fd=%d,backlog=%d", s, backlog);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ /* limit the "backlog" parameter to fit in an u8_t */
+ if (backlog < 0)
+ {
+ backlog = 0;
+ }
+
+ if (backlog > 0xff)
+ {
+ backlog = 0xff;
+ }
+
+ return sk->fdopt->listen(sk, backlog);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : connect
+* Input : int
+* connect
+* (int s
+* const struct sockaddr * name
+* socklen_t namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, connect,
+ (int s, const struct sockaddr * name, socklen_t namelen))
+{
+ NSSBR_LOGDBG("connect]fd=%d,name=%p,namelen=%d", s, name, namelen);
+ if (!name)
+ {
+ NSSBR_LOGERR("name is null]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (!
+ (namelen == sizeof(struct sockaddr_in)
+ && (name->sa_family == AF_INET)))
+ {
+ NSSBR_LOGERR("parameter invalid]fd=%d,domain=%u,namelen=%d", s,
+ name->sa_family, namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ NSSBR_LOGERR("get socket failed]fd=%d", s);
+ return -1;
+ }
+
+ return sk->fdopt->connect(sk, name, namelen);
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_sock_name
+* Description : check name
+* Input : int s
+* struct sockaddr * name
+* socklen_t * namelen
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int
+sbr_check_sock_name(int s, struct sockaddr *name, socklen_t * namelen)
+{
+ if (!name || !namelen)
+ {
+ NSSBR_LOGERR("name or namelen is null]fd=%d", s);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ if (*namelen & 0x80000000)
+ {
+ NSSBR_LOGERR("namelen is not ok]fd=%d,namelen=%d", s, *namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : getpeername
+* Input : int
+* getpeername
+* (int s
+* struct sockaddr * name
+* socklen_t * namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, getpeername,
+ (int s, struct sockaddr * name, socklen_t * namelen))
+{
+ NSSBR_LOGDBG("getpeername]fd=%d", s);
+ int ret = sbr_check_sock_name(s, name, namelen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ ret = sk->fdopt->getpeername(sk, name, namelen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : getsockname
+* Input : int
+* getsockname
+* (int s
+* struct sockaddr * name
+* socklen_t * namelen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, getsockname,
+ (int s, struct sockaddr * name, socklen_t * namelen))
+{
+ NSSBR_LOGDBG("getsockname]fd=%d", s);
+ int ret = sbr_check_sock_name(s, name, namelen);
+
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ ret = sk->fdopt->getsockname(sk, name, namelen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : setsockopt
+* Input : int
+* setsockopt
+* (int s
+* int level
+* int optname
+* const void * optval
+* socklen_t optlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, setsockopt,
+ (int s, int level, int optname, const void *optval,
+ socklen_t optlen))
+{
+ NSSBR_LOGDBG("setsockopt]fd=%d,level=%d,optname=%d,optval=%p,optlen=%d",
+ s, level, optname, optval, optlen);
+ if (!optval)
+ {
+ NSSBR_LOGERR("optval is null]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->setsockopt(sk, level, optname, optval, optlen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : getsockopt
+* Input : int
+* getsockopt
+* (int s
+* int level
+* int optname
+* void * optval
+* socklen_t * optlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, getsockopt,
+ (int s, int level, int optname, void *optval,
+ socklen_t * optlen))
+{
+ NSSBR_LOGDBG("getsockopt]fd=%d,level=%d,optname=%d,optval=%p,optlen=%p",
+ s, level, optname, optval, optlen);
+ if (!optval || !optlen)
+ {
+ NSSBR_LOGERR("optval or optlen is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->getsockopt(sk, level, optname, optval, optlen);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : ioctl
+* Input : int
+* ioctl
+* (int s
+* unsigned long cmd
+* ...)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, ioctl, (int s, unsigned long cmd, ...))
+{
+ NSSBR_LOGDBG("ioctl]fd=%d,cmd=%lu", s, cmd);
+ va_list va;
+ va_start(va, cmd);
+ void *arg = va_arg(va, void *);
+ va_end(va);
+
+ if (!arg)
+ {
+ NSSBR_LOGERR("parameter is not ok]fd=%d", s);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->ioctl(sk, cmd, arg);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : fcntl
+* Input : int
+* fcntl
+* (int s
+* int cmd
+* ...)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, fcntl, (int s, int cmd, ...))
+{
+ NSSBR_LOGDBG("fcntl]fd=%d,cmd=%d", s, cmd);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ va_list va;
+ va_start(va, cmd);
+ long arg = va_arg(va, long);
+ va_end(va);
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->fcntl(sk, cmd, arg);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : recvfrom
+* Input : int
+* recvfrom
+* (int s
+* void * mem
+* size_t len
+* int flags
+* struct sockaddr * from
+* socklen_t * fromlen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, recvfrom,
+ (int s, void *mem, size_t len, int flags,
+ struct sockaddr * from, socklen_t * fromlen))
+{
+ NSSBR_LOGDBG("recvfrom]fd=%d,mem=%p,len=%d,flags=%d,from=%p,fromlen=%p",
+ s, mem, len, flags, from, fromlen);
+
+ if (0 == len)
+ {
+ NSSBR_LOGDBG("len is zero]fd=%d,len=%u", s, (u32) len);
+ return 0; //return directly, don't change the last errno.
+ }
+
+ if (!mem)
+ {
+ NSSBR_LOGERR("mem is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (fromlen && (*((int *) fromlen) < 0))
+ {
+ NSSBR_LOGERR("fromlen is not ok]fd=%d,fromlen=%d", s, *fromlen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->recvfrom(sk, mem, len, flags, from, fromlen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : read
+* Input : int
+* read
+* (int s
+* void * mem
+* size_t len)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, read, (int s, void *mem, size_t len))
+{
+ NSSBR_LOGDBG("read]fd=%d,mem=%p,len=%d", s, mem, len);
+ return CALL_SBR_INTERCEPT(recvfrom, (s, mem, len, 0, NULL, NULL));
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_iov
+* Description : check iov
+* Input : int s
+* const struct iovec * iov
+* int iovcnt
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int sbr_check_iov(int s, const struct iovec *iov, int iovcnt)
+{
+ if ((!iov) || (iovcnt <= 0))
+ {
+ NSSBR_LOGERR("iov is NULL or iovcn <=0]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ int i;
+ for (i = 0; i < iovcnt; ++i)
+ {
+ if (!iov[i].iov_base && (iov[i].iov_len != 0))
+ {
+ NSSBR_LOGERR("iov is not ok]fd=%d,iov_base=%p,iov_len=%d", s,
+ iov[i].iov_base, iov[i].iov_len);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : readv
+* Input : int
+* readv
+* (int s
+* const struct iovec * iov
+* int iovcnt)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, readv, (int s, const struct iovec * iov, int iovcnt))
+{
+ NSSBR_LOGDBG("readv]fd=%d,iov=%p,iovcnt=%d", s, iov, iovcnt);
+
+ if (sbr_check_iov(s, iov, iovcnt) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->readv(sk, iov, iovcnt);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : recv
+* Input : int
+* recv
+* (int s
+* void * mem
+* size_t len
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, recv, (int s, void *mem, size_t len, int flags))
+{
+ NSSBR_LOGDBG("recv]fd=%d,mem=%p,len=%d,flags=%d", s, mem, len, flags);
+ return CALL_SBR_INTERCEPT(recvfrom, (s, mem, len, flags, NULL, NULL));
+}
+
+/*****************************************************************************
+* Prototype : sbr_check_msg
+* Description : check msg
+* Input : int s
+* const struct msghdr * msg
+* Output : None
+* Return Value : static inline int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline int sbr_check_msg(int s, const struct msghdr *msg)
+{
+ if (!msg)
+ {
+ NSSBR_LOGERR("msg is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ if (msg->msg_name && ((int) msg->msg_namelen < 0))
+ {
+ NSSBR_LOGERR("msg_namelen is not ok]fd=%d,msg_namelen=%d", s,
+ msg->msg_namelen);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ return sbr_check_iov(s, msg->msg_iov, msg->msg_iovlen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : recvmsg
+* Input : int
+* recvmsg
+* (int s
+* struct msghdr * msg
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, recvmsg, (int s, struct msghdr * msg, int flags))
+{
+ NSSBR_LOGDBG("recvmsg]fd=%d,msg=%p,flags=%d", s, msg, flags);
+
+ if (sbr_check_msg(s, msg) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->recvmsg(sk, msg, flags);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : send
+* Input : int
+* send
+* (int s
+* const void * data
+* size_t size
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, send,
+ (int s, const void *data, size_t size, int flags))
+{
+ NSSBR_LOGDBG("send]fd=%d,data=%p,size=%zu,flags=%d", s, data, size,
+ flags);
+ if (!data)
+ {
+ NSSBR_LOGERR("data is NULL]fd=%d", s);
+ sbr_set_errno(EFAULT);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->send(sk, data, size, flags);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : sendmsg
+* Input : int
+* sendmsg
+* (int s
+* const struct msghdr * msg
+* int flags)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, sendmsg, (int s, const struct msghdr * msg, int flags))
+{
+ NSSBR_LOGDBG("sendmsg]fd=%d,msg=%p,flags=%d", s, msg, flags);
+
+ if (sbr_check_msg(s, msg) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->sendmsg(sk, msg, flags);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : sendto
+* Input : int
+* sendto
+* (int s
+* const void * data
+* size_t size
+* int flags
+* const struct sockaddr * to
+* socklen_t tolen)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, sendto,
+ (int s, const void *data, size_t size, int flags,
+ const struct sockaddr * to, socklen_t tolen))
+{
+ NSSBR_LOGDBG("sendto]fd=%d,data=%p,size=%zu,flags=%d,to=%p,tolen=%d", s,
+ data, size, flags, to, tolen);
+ if ((data == NULL) || (flags < 0))
+ {
+ NSSBR_LOGERR("parameter is not ok]fd=%d,data=%p,size=%zu,flags=%d", s,
+ data, size, flags);
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->sendto(sk, data, size, flags, to, tolen);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : write
+* Input : int
+* write
+* (int s
+* const void * data
+* size_t size)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, write, (int s, const void *data, size_t size))
+{
+ NSSBR_LOGDBG("write]fd=%d,data=%p,size=%zu", s, data, size);
+ return CALL_SBR_INTERCEPT(send, (s, data, size, 0));
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : writev
+* Input : int
+* writev
+* (int s
+* const struct iovec * iov
+* int iovcnt)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(ssize_t, writev, (int s, const struct iovec * iov, int iovcnt))
+{
+ NSSBR_LOGDBG("writev]fd=%d,iov=%p,iovcnt=%d", s, iov, iovcnt);
+
+ if (sbr_check_iov(s, iov, iovcnt) != 0)
+ {
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->writev(sk, iov, iovcnt);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : shutdown
+* Input : int
+* shutdown
+* (int s
+* int how)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, shutdown, (int s, int how))
+{
+ NSSBR_LOGDBG("shutdown]fd=%d,how=%d", s, how);
+ if ((how != SHUT_RD) && (how != SHUT_WR) && (how != SHUT_RDWR))
+ {
+ sbr_set_errno(EINVAL);
+ return -1;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ sk->fdopt->lock_common(sk);
+ int ret = sk->fdopt->shutdown(sk, how);
+ sk->fdopt->unlock_common(sk);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : close
+* Input : int
+* close
+* (int s)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(int, close, (int s))
+{
+ NSSBR_LOGDBG("close]fd=%d", s);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ int ret = sk->fdopt->close(sk);
+ sbr_free_sk(sk);
+ return ret;
+}
+
+SBR_INTERCEPT(int, select,
+ (int nfds, fd_set * readfd, fd_set * writefd,
+ fd_set * exceptfd, struct timeval * timeout))
+{
+ return lwip_try_select(nfds, readfd, writefd, exceptfd, timeout);
+}
+
+SBR_INTERCEPT(int, ep_getevt, (int profd))
+{
+ NSSBR_LOGDBG("proFD=%d", profd);
+ sbr_socket_t *sk = sbr_lookup_sk(profd);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->ep_getevt(sk);
+}
+
+SBR_INTERCEPT(void *, ep_triggle,
+ (int proFD, int triggle_ops, void *epinfo, void *epitem))
+{
+ NSSBR_LOGDBG("proFD=%d,triggle_ops=%d,epinfo=%p,epi=%p", proFD,
+ triggle_ops, epinfo, epitem);
+ sbr_socket_t *sk = sbr_lookup_sk(proFD);
+
+ if (!sk)
+ {
+ return NULL;
+ }
+
+ return sk->fdopt->ep_triggle(sk, triggle_ops, epinfo, epitem);
+}
+
+SBR_INTERCEPT(int, peak, (int s))
+{
+ NSSBR_LOGDBG("]fd=%d", s);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->peak(sk);
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : set_app_info
+* Input : int
+* set_app_info
+* (int s
+* void* app_info)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(void, set_app_info, (int s, void *app_info))
+{
+ NSSBR_LOGDBG("set_app_info]fd=%d", s);
+
+ if (!app_info)
+ {
+ NSSBR_LOGERR("invalid param, app_info is NULL]");
+ return;
+ }
+
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->set_app_info(sk, app_info);
+}
+
+/* app send its version info to nStackMain */
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : sbr_app_touch
+* Input : int
+* sbr_app_touch
+* ()
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(void, app_touch, (void))
+{
+ NSSBR_LOGDBG("sbr_app_touch() is called]");
+
+ sbr_app_touch_in();
+}
+
+/*****************************************************************************
+* Prototype : SBR_INTERCEPT
+* Description : set_close_status
+* Input : void
+* set_close_stat
+* (int s
+* int flag)
+* Output : None
+* Return Value :
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+SBR_INTERCEPT(void, set_close_stat, (int s, int flag))
+{
+ NSSBR_LOGDBG("]fd=%d", s);
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return;
+ }
+ if (sk->fdopt->set_close_stat)
+ {
+ sk->fdopt->set_close_stat(sk, flag);
+ }
+
+}
+
+SBR_INTERCEPT(int, fd_alloc, ())
+{
+ return sbr_socket(AF_INET, SOCK_STREAM, 0);
+}
+
+SBR_INTERCEPT(int, fork_init_child, (pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG("fork_init_child() is called]");
+ return sbr_fork_protocol();
+}
+
+SBR_INTERCEPT(void, fork_parent_fd, (int s, pid_t p))
+{
+ NSSBR_LOGDBG("fork_parent_fd() is called]");
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->fork_parent(sk, p);
+}
+
+SBR_INTERCEPT(void, fork_child_fd, (int s, pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG("fork_child_fd() is called]");
+ sbr_socket_t *sk = sbr_lookup_sk(s);
+
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->fork_child(sk, p, c);
+
+}
+
+SBR_INTERCEPT(void, fork_free_fd, (int s))
+{
+ NSSBR_LOGDBG("fork_free_fd() is called]");
+ sbr_free_fd(s);
+}
+
+SBR_INTERCEPT(void *, get_ip_shmem, (void))
+{
+ lwip_rd_table = nstack_rd_malloc("lwip_rd_table");
+
+ if (!lwip_rd_table)
+ {
+ NSSOC_LOGERR("lwip rd table create failed!");
+ return NULL;
+ }
+
+ if (nstack_rd_parse("lwip", lwip_rd_table))
+ {
+ NSSOC_LOGWAR("lwip parse rd data failed, load default instead");
+ }
+
+ return lwip_rd_table;
+}
+
+SBR_INTERCEPT(int, module_init_pre,
+ (void *op1, void *op2, int memtype, int pooltype))
+{
+ int i;
+ nsfw_mem_attr *mem_ops = (nsfw_mem_attr *) op1;
+ nsfw_ring_ops *ring_ops = (nsfw_ring_ops *) op2;
+ nsfw_ring_ops *tmp_ring_ops;
+
+ if (!mem_ops || !ring_ops)
+ {
+ return -1;
+ }
+
+ mem_ops[NSFW_SHMEM].stmemop = &g_shmem_ops;
+ mem_ops[NSFW_NSHMEM].stmemop = &g_nshmem_ops;
+
+ tmp_ring_ops = (nsfw_ring_ops *) g_ring_ops_arry_lwip;
+ for (i = 0; i < memtype * pooltype; i++)
+ {
+ ring_ops[i] = tmp_ring_ops[i];
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nstack_stack_register
+* Description : reg api to nsocket
+* Input : nstack_socket_ops* ops
+* nstack_event_ops *val
+* nstack_proc_ops *deal
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int
+lwip_stack_register(nstack_socket_ops * ops, nstack_event_ops * val,
+ nstack_proc_ops * deal)
+{
+ if (!ops || !val || !val->handle)
+ {
+ return -1;
+ }
+
+#undef NSTACK_MK_DECL
+#define NSTACK_MK_DECL(ret, fn, args) \
+ ops->pf ## fn = (typeof(((nstack_socket_ops*)0)->pf ## fn))dlsym(val->handle, "sbr_" # fn);
+#include "declare_syscalls.h.tmpl"
+
+ deal->module_init = sbr_init_res;
+ deal->fork_init_child = GET_SBR_INTERCEPT(fork_init_child);
+ deal->fork_fd = GET_SBR_INTERCEPT(fork_child_fd);
+ deal->fork_free_fd = GET_SBR_INTERCEPT(fork_free_fd);
+ deal->ep_getEvt = GET_SBR_INTERCEPT(ep_getevt);
+ deal->ep_triggle = GET_SBR_INTERCEPT(ep_triggle);
+ deal->peak = GET_SBR_INTERCEPT(peak);
+ //deal->stack_alloc_fd = GET_SBR_INTERCEPT (fd_alloc); /*alloc a fd id for epoll */
+ deal->fork_parent_fd = GET_SBR_INTERCEPT(fork_parent_fd);
+ deal->get_ip_shmem = GET_SBR_INTERCEPT(get_ip_shmem);
+ deal->module_init_pre = GET_SBR_INTERCEPT(module_init_pre);
+ return 0;
+}