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.txt30
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_err.h191
-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.h99
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.c88
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.h128
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_socket.c1231
8 files changed, 2040 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..42ab4a4
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/CMakeLists.txt
@@ -0,0 +1,30 @@
+#########################################################################
+#
+# 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(nstack SHARED ${SBR})
+TARGET_LINK_LIBRARIES(nstack -Wl,--whole-archive socket -Wl,--no-whole-archive dmm_api nStackMaintain)
+ADD_DEPENDENCIES(nstack socket DPDK)
+INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_LIST_DIR}/../include
+ ${PAL_H_DIRECTORIES}
+)
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..be3bc3b
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_err.h
@@ -0,0 +1,191 @@
+/*
+*
+* 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..0daa465
--- /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..86e8345
--- /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..1c0fb1e
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
@@ -0,0 +1,99 @@
+/*
+*
+* 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 *);
+ unsigned int (*ep_ctl) (sbr_socket_t *, int triggle_ops,
+ struct epoll_event * event, void *pdata);
+ unsigned int (*ep_getevt) (sbr_socket_t *, unsigned int events);
+ 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 ();
+
+sbr_fdopt *sbr_get_fdopt (int domain, int type, int protocol);
+void sbr_app_touch_in (void); /*app send its version info to nStackMain */
+
+#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..f40f101
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.c
@@ -0,0 +1,88 @@
+/*
+*
+* 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..54729d4
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
@@ -0,0 +1,128 @@
+/*
+*
+* 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;
+}
+
+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..47aefda
--- /dev/null
+++ b/stacks/lwip_stack/src/sbr/sbr_socket.c
@@ -0,0 +1,1231 @@
+/*
+*
+* 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 "nstack_dmm_api.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
+
+/*****************************************************************************
+* 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 (int, 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 -1;
+}
+
+SBR_INTERCEPT (unsigned int, ep_getevt,
+ (int epfd, int profd, unsigned int events))
+{
+ NSSBR_LOGDBG ("epfd= %d, proFD=%d,epi=0x%x", epfd, profd, events);
+ sbr_socket_t *sk = sbr_lookup_sk (profd);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->ep_getevt (sk, events);
+}
+
+SBR_INTERCEPT (unsigned int, ep_ctl,
+ (int epfd, int profd, int triggle_ops,
+ struct epoll_event * event, void *pdata))
+{
+ NSSBR_LOGDBG ("epfd = %d, proFD=%d,triggle_ops=%d,pdata=%p", epfd, profd,
+ triggle_ops, pdata);
+ sbr_socket_t *sk = sbr_lookup_sk (profd);
+
+ if (!sk)
+ {
+ return -1;
+ }
+
+ return sk->fdopt->ep_ctl (sk, triggle_ops, event, pdata);
+}
+
+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);
+}
+
+/*****************************************************************************
+* 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
+nstack_stack_register (nstack_proc_cb * ops, nstack_event_cb * val)
+{
+ if (!ops || !val || !val->handle)
+ {
+ return -1;
+ }
+
+#undef NSTACK_MK_DECL
+#define NSTACK_MK_DECL(ret, fn, args) \
+ (ops->socket_ops).pf ## fn = (typeof(((nstack_socket_ops*)0)->pf ## fn))dlsym(val->handle, "sbr_" # fn);
+#include "declare_syscalls.h"
+
+ (ops->extern_ops).module_init = sbr_init_res;
+ (ops->extern_ops).ep_getevt = GET_SBR_INTERCEPT (ep_getevt);
+ (ops->extern_ops).ep_ctl = GET_SBR_INTERCEPT (ep_ctl);
+ (ops->extern_ops).peak = GET_SBR_INTERCEPT (peak);
+ (ops->extern_ops).stack_alloc_fd = GET_SBR_INTERCEPT (fd_alloc); /*alloc a fd id for epoll */
+ return 0;
+}