summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/src/sbr
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/lwip_stack/src/sbr')
-rw-r--r--stacks/lwip_stack/src/sbr/CMakeLists.txt37
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_err.h190
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_index_ring.c212
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_index_ring.h61
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_protocol_api.h102
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.c87
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.h155
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_socket.c1324
8 files changed, 2168 insertions, 0 deletions
diff --git a/stacks/lwip_stack/src/sbr/CMakeLists.txt b/stacks/lwip_stack/src/sbr/CMakeLists.txt
new file mode 100644
index 0000000..8bd5007
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/CMakeLists.txt
@@ -0,0 +1,37 @@
+#########################################################################
+#
+# 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.
+#########################################################################
+
+if(WITH_HAL_LIB)
+else()
+ SET(PAL_H_DIRECTORIES "/usr/include/dpdk/")
+endif()
+
+
+FILE(GLOB SBR *.c)
+ADD_LIBRARY(lwip_dpdk SHARED ${SBR})
+TARGET_LINK_LIBRARIES(lwip_dpdk -Wl,--whole-archive socket nsfw_mem -Wl,--no-whole-archive rte_eal rte_mempool rte_ring rte_mbuf)
+ADD_DEPENDENCIES(lwip_dpdk socket DPDK)
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_LIST_DIR}/../include
+ ${PAL_H_DIRECTORIES}
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../stacks/lwip_stack/src/mem/include/
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../src/framework/include/common/generic/
+ ${CMAKE_CURRENT_LIST_DIR}/../mem/nsfw_shmem/
+ ${CMAKE_CURRENT_LIST_DIR}/../mem/nsfw_nshmem/
+)
diff --git a/stacks/lwip_stack/src/sbr/sbr_err.h b/stacks/lwip_stack/src/sbr/sbr_err.h
new file mode 100644
index 0000000..96b5399
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_err.h
@@ -0,0 +1,190 @@
+/*
+*
+* 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.
+*/
+
+#ifndef SBR_ERR_H
+#define SBR_ERR_H
+#include <errno.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#ifdef SBR_PROVIDE_ERRNO
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Arg list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No stored locks available */
+#define ENOSYS 38 /* Function not implemented */
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+
+#define EDEADLOCK EDEADLK
+
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale NFS file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EDQUOT 122 /* Quota exceeded */
+
+#define ENOMEDIUM 123 /* No medium found */
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+
+#define ENSROK 0
+#define ENSRNODATA 160
+#define ENSRFORMERR 161
+#define ENSRSERVFAIL 162
+#define ENSRNOTFOUND 163
+#define ENSRNOTIMP 164
+#define ENSRREFUSED 165
+#define ENSRBADQUERY 166
+#define ENSRBADNAME 167
+#define ENSRBADFAMILY 168
+#define ENSRBADRESP 169
+#define ENSRCONNREFUSED 170
+#define ENSRTIMEOUT 171
+#define ENSROF 172
+#define ENSRFILE 173
+#define ENSRNOMEM 174
+#define ENSRDESTRUCTION 175
+#define ENSRQUERYDOMAINTOOLONG 176
+#define ENSRCNAMELOOP 177
+#define OPTION_DEG 200
+
+#endif
+
+static inline void sbr_set_errno(int err)
+{
+ errno = err;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_index_ring.c b/stacks/lwip_stack/src/sbr/sbr_index_ring.c
new file mode 100644
index 0000000..b684918
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_index_ring.c
@@ -0,0 +1,212 @@
+/*
+*
+* 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 <string.h>
+#include "sbr_index_ring.h"
+#include "nstack_securec.h"
+#include "common_mem_common.h"
+#include "common_func.h"
+
+/*****************************************************************************
+* Prototype : sbr_init_index_ring
+* Description : init index ring
+* Input : sbr_index_ring* ring
+* u32 num
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void sbr_init_index_ring(sbr_index_ring * ring, u32 num)
+{
+ u32 loop;
+
+ ring->head = 0;
+ ring->tail = 0;
+ ring->num = num;
+ ring->mask = num - 1;
+
+ for (loop = 0; loop < num; loop++)
+ {
+ ring->nodes[loop].ver = (loop - num);
+ ring->nodes[loop].val = 0;
+ }
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_index_ring
+* Description : create index ring
+* Input : u32 num
+* Output : None
+* Return Value : sbr_index_ring*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+sbr_index_ring *sbr_create_index_ring(u32 num)
+{
+ num = common_mem_align32pow2(num + 1);
+ sbr_index_ring *ring =
+ (sbr_index_ring *) malloc(sizeof(sbr_index_ring) +
+ num * sizeof(sbr_index_node));
+ if (!ring)
+ {
+ return NULL;
+ }
+
+ sbr_init_index_ring(ring, num);
+ return ring;
+}
+
+/*****************************************************************************
+* Prototype : sbr_index_ring_enqueue
+* Description : enqueue data,val != 0
+* Input : sbr_index_ring* ring
+* i32 val
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int sbr_index_ring_enqueue(sbr_index_ring * ring, i32 val)
+{
+ if (0 == val)
+ {
+ return -1;
+ }
+
+ sbr_index_node expect_node;
+ sbr_index_node cur_node;
+ u32 tmp_head;
+ u32 tmp_tail;
+ u32 cur_head = ring->head;
+ u32 mask = ring->mask;
+ u32 size = ring->num;
+
+ do
+ {
+ tmp_tail = ring->tail;
+ if (tmp_tail + size - cur_head == 0)
+ {
+ if (ring->nodes[tmp_tail & mask].val == 0)
+ {
+ (void) __sync_bool_compare_and_swap(&ring->tail, tmp_tail,
+ tmp_tail + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ expect_node.ver = cur_head - size;
+ expect_node.val = 0;
+
+ cur_node.ver = cur_head;
+ cur_node.val = val;
+
+ if ((ring->nodes[cur_head & mask].ver == expect_node.ver)
+ && __sync_bool_compare_and_swap(&ring->
+ nodes[cur_head & mask].data,
+ expect_node.data, cur_node.data))
+ {
+ tmp_head = ring->head;
+ if ((tmp_head - cur_head > 0x80000000)
+ && (0 == (cur_head & 0x11)))
+ {
+ (void) __sync_bool_compare_and_swap(&ring->head, tmp_head,
+ cur_head);
+ }
+
+ break;
+ }
+
+ tmp_head = ring->head;
+ cur_head = cur_head - tmp_head < mask - 1 ? cur_head + 1 : tmp_head;
+ }
+ while (1);
+
+ return 1;
+}
+
+/*****************************************************************************
+* Prototype : sbr_index_ring_dequeue
+* Description : dequeue
+* Input : sbr_index_ring* ring
+* i32* val
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int sbr_index_ring_dequeue(sbr_index_ring * ring, i32 * val)
+{
+ u32 cur_tail;
+ u32 tmp_tail;
+ u32 tmp_head;
+ u32 mask = ring->mask;
+ sbr_index_node null_node;
+ sbr_index_node expect_node;
+
+ cur_tail = ring->tail;
+ do
+ {
+ tmp_head = ring->head;
+ if (cur_tail == tmp_head)
+ {
+ if (0 != (ring->nodes[tmp_head & mask].val))
+ {
+ (void) __sync_bool_compare_and_swap(&ring->head, tmp_head,
+ tmp_head + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ null_node.ver = cur_tail;
+ null_node.val = 0;
+ expect_node = ring->nodes[cur_tail & mask];
+
+ if ((null_node.ver == expect_node.ver) && (expect_node.val)
+ && __sync_bool_compare_and_swap(&ring->
+ nodes[cur_tail & mask].data,
+ expect_node.data, null_node.data))
+
+ {
+ *val = expect_node.val;
+ tmp_tail = ring->tail;
+ if ((tmp_tail - cur_tail > 0x80000000)
+ && (0 == (cur_tail & 0x11)))
+ {
+ (void) __sync_bool_compare_and_swap(&ring->tail, tmp_tail,
+ cur_tail);
+ }
+
+ break;
+ }
+
+ tmp_tail = ring->tail;
+ cur_tail = cur_tail - tmp_tail < mask - 1 ? cur_tail + 1 : tmp_tail;
+ }
+ while (1);
+
+ return 1;
+}
diff --git a/stacks/lwip_stack/src/sbr/sbr_index_ring.h b/stacks/lwip_stack/src/sbr/sbr_index_ring.h
new file mode 100644
index 0000000..7a1e396
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_index_ring.h
@@ -0,0 +1,61 @@
+/*
+*
+* 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.
+*/
+
+#ifndef _SBR_INDEX_RING_H_
+#define _SBR_INDEX_RING_H_
+
+#include "types.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ volatile u32 ver;
+ volatile u32 val;
+ };
+ u64 data;
+ };
+} sbr_index_node;
+
+typedef struct
+{
+ volatile u32 head;
+ i8 cache_space[124];
+ volatile u32 tail;
+ u32 num;
+ u32 mask;
+ sbr_index_node nodes[0];
+} sbr_index_ring;
+
+sbr_index_ring *sbr_create_index_ring(u32 num);
+int sbr_index_ring_enqueue(sbr_index_ring * ring, i32 val);
+int sbr_index_ring_dequeue(sbr_index_ring * ring, i32 * val);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_protocol_api.h b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
new file mode 100644
index 0000000..16608bc
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
@@ -0,0 +1,102 @@
+/*
+*
+* 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.
+*/
+
+#ifndef SBR_PROTOCOL_API_H
+#define SBR_PROTOCOL_API_H
+#include <sys/uio.h>
+#include <sys/epoll.h>
+#include <netinet/in.h>
+#include "sbr_err.h"
+#include "nsfw_msg_api.h"
+#include "nsfw_mt_config.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#ifndef SBR_MAX_INTEGER
+#define SBR_MAX_INTEGER 0x7FFFFFFF
+#endif
+
+#ifndef socklen_t
+#define socklen_t u32
+#endif
+
+#define SBR_MAX_FD_NUM MAX_SOCKET_NUM
+
+typedef struct sbr_socket_s sbr_socket_t;
+typedef struct
+{
+ int (*socket) (sbr_socket_t *, int, int, int);
+ int (*bind) (sbr_socket_t *, const struct sockaddr *, socklen_t);
+ int (*listen) (sbr_socket_t *, int);
+ int (*accept) (sbr_socket_t *, sbr_socket_t *, struct sockaddr *,
+ socklen_t *);
+ int (*accept4) (sbr_socket_t *, sbr_socket_t *, struct sockaddr *,
+ socklen_t *, int);
+ int (*connect) (sbr_socket_t *, const struct sockaddr *, socklen_t);
+ int (*shutdown) (sbr_socket_t *, int);
+ int (*getsockname) (sbr_socket_t *, struct sockaddr *, socklen_t *);
+ int (*getpeername) (sbr_socket_t *, struct sockaddr *, socklen_t *);
+ int (*getsockopt) (sbr_socket_t *, int, int, void *, socklen_t *);
+ int (*setsockopt) (sbr_socket_t *, int, int, const void *, socklen_t);
+ int (*recvfrom) (sbr_socket_t *, void *, size_t, int, struct sockaddr *,
+ socklen_t *);
+ int (*readv) (sbr_socket_t *, const struct iovec *, int);
+ int (*recvmsg) (sbr_socket_t *, struct msghdr *, int);
+ int (*send) (sbr_socket_t *, const void *, size_t, int);
+ int (*sendto) (sbr_socket_t *, const void *, size_t, int,
+ const struct sockaddr *, socklen_t);
+ int (*sendmsg) (sbr_socket_t *, const struct msghdr *, int);
+ int (*writev) (sbr_socket_t *, const struct iovec *, int);
+ int (*fcntl) (sbr_socket_t *, int, long);
+ int (*ioctl) (sbr_socket_t *, unsigned long, void *);
+ int (*close) (sbr_socket_t *);
+ int (*peak) (sbr_socket_t *);
+ void (*lock_common) (sbr_socket_t *);
+ void (*unlock_common) (sbr_socket_t *);
+ void (*fork_parent) (sbr_socket_t *, pid_t);
+ void (*fork_child) (sbr_socket_t *, pid_t, pid_t);
+ void (*(*ep_triggle) (sbr_socket_t *, int triggle_ops, void *, void *));
+ int (*ep_getevt) (sbr_socket_t *);
+ void (*set_app_info) (sbr_socket_t *, void *appinfo);
+ void (*set_close_stat) (sbr_socket_t *, int flag);
+} sbr_fdopt;
+
+struct sbr_socket_s
+{
+ int fd;
+ sbr_fdopt *fdopt;
+ void *stack_obj;
+ void *sk_obj;
+};
+
+int sbr_init_protocol();
+int sbr_fork_protocol();
+sbr_fdopt *sbr_get_fdopt(int domain, int type, int protocol);
+void sbr_app_touch_in(void); /*app send its version info to nStackMain */
+int lwip_try_select(int fdsize, fd_set * fdread, fd_set * fdwrite,
+ fd_set * fderr, struct timeval *timeout);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/src/sbr/sbr_res_mgr.c b/stacks/lwip_stack/src/sbr/sbr_res_mgr.c
new file mode 100644
index 0000000..3758084
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.c
@@ -0,0 +1,87 @@
+/*
+*
+* 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 "nstack_securec.h"
+#include "sbr_res_mgr.h"
+
+sbr_res_group g_res_group = { };
+
+/*****************************************************************************
+* Prototype : sbr_init_sk
+* Description : init sock pool
+* Input : None
+* Output : None
+* Return Value : static int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+NSTACK_STATIC int sbr_init_sk()
+{
+ sbr_index_ring *ring = sbr_create_index_ring(SBR_MAX_FD_NUM - 1);
+
+ if (!ring)
+ {
+ NSSBR_LOGERR("init ring failed");
+ return -1;
+ }
+
+ int i;
+ /*the queue can't accept value=0, so i begin with 1 */
+ for (i = 1; i <= SBR_MAX_FD_NUM; ++i)
+ {
+ g_res_group.sk[i].fd = i;
+ if (sbr_index_ring_enqueue(ring, i) != 1)
+ {
+ NSSBR_LOGERR
+ ("sbr_index_ring_enqueue failed, this can not happen");
+ free(ring);
+ return -1;
+ }
+ }
+
+ g_res_group.sk_ring = ring;
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : sbr_init_res
+* Description : init sbr res
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int sbr_init_res()
+{
+ if (sbr_init_sk() != 0)
+ {
+ return -1;
+ }
+
+ NSSBR_LOGDBG("init socket ok");
+
+ if (sbr_init_protocol() != 0)
+ {
+ return -1;
+ }
+
+ NSSBR_LOGDBG("init protocol ok");
+
+ return 0;
+}
diff --git a/stacks/lwip_stack/src/sbr/sbr_res_mgr.h b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
new file mode 100644
index 0000000..d597ef7
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
@@ -0,0 +1,155 @@
+/*
+*
+* 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.
+*/
+
+#ifndef SBR_RES_MGR_H
+#define SBR_RES_MGR_H
+#include "sbr_protocol_api.h"
+#include "sbr_index_ring.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+typedef struct
+{
+ sbr_index_ring *sk_ring;
+ sbr_socket_t sk[SBR_MAX_FD_NUM + 1]; /* unuse index 0 */
+} sbr_res_group;
+
+extern sbr_res_group g_res_group;
+
+/*****************************************************************************
+* Prototype : sbr_malloc_sk
+* Description : malloc sock
+* Input : None
+* Output : None
+* Return Value : static inline sbr_socket_t *
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline sbr_socket_t *sbr_malloc_sk()
+{
+ int fd;
+
+ if (sbr_index_ring_dequeue(g_res_group.sk_ring, &fd) != 1)
+ {
+ NSSBR_LOGERR("malloc sk failed]");
+ sbr_set_errno(EMFILE);
+ return NULL;
+ }
+
+ NSSBR_LOGDBG("malloc sk ok]fd=%d", fd);
+ return &g_res_group.sk[fd];
+}
+
+/*****************************************************************************
+* Prototype : sbr_free_sk
+* Description : free sock
+* Input : sbr_socket_t * sk
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void sbr_free_sk(sbr_socket_t * sk)
+{
+ sk->fdopt = NULL;
+ sk->sk_obj = NULL;
+ sk->stack_obj = NULL;
+
+ if (sbr_index_ring_enqueue(g_res_group.sk_ring, sk->fd) != 1)
+ {
+ NSSBR_LOGERR("sbr_index_ring_enqueue failed, this can not happen");
+ }
+
+ NSSBR_LOGDBG("free sk ok]fd=%d", sk->fd);
+}
+
+/*****************************************************************************
+* Prototype : sbr_lookup_sk
+* Description : lookup socket
+* Input : int fd
+* Output : None
+* Return Value : static inline sbr_socket_t *
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline sbr_socket_t *sbr_lookup_sk(int fd)
+{
+ if ((fd < 1) || (fd > SBR_MAX_FD_NUM))
+ {
+ NSSBR_LOGERR("fd is not ok]fd=%d", fd);
+ sbr_set_errno(EBADF);
+ return NULL;
+ }
+
+ sbr_socket_t *sk = &g_res_group.sk[fd];
+ if (!sk->sk_obj || !sk->stack_obj)
+ {
+ NSSBR_LOGERR
+ ("data in sk is error, this can not happen]fd=%d,sk_obj=%p,stack_obj=%p",
+ fd, sk->sk_obj, sk->stack_obj);
+ sbr_set_errno(EBADF);
+ return NULL;
+ }
+
+ return sk;
+}
+
+/*****************************************************************************
+* Prototype : sbr_free_sk
+* Description : free sock
+* Input : sbr_socket_t * sk
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void sbr_free_fd(int fd)
+{
+ if ((fd < 1) || (fd > SBR_MAX_FD_NUM))
+ {
+ NSSBR_LOGERR("fd is not ok]fd=%d", fd);
+ sbr_set_errno(EBADF);
+ return;
+ }
+
+ sbr_socket_t *sk = &g_res_group.sk[fd];
+ if (!sk->fdopt && !sk->sk_obj && !sk->stack_obj)
+ {
+ NSSBR_LOGERR
+ ("can't free empty fd] fd=%d, fdopt=%p, sk_obj=%p, stack_obj=%p",
+ fd, sk->fdopt, sk->sk_obj, sk->stack_obj);
+ return;
+ }
+ sbr_free_sk(sk);
+}
+
+int sbr_init_res();
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
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;
+}