diff options
author | sharath reddy <bs.reddy@huawei.com> | 2019-06-04 11:53:49 +0530 |
---|---|---|
committer | sharath reddy <bs.reddy@huawei.com> | 2019-06-04 20:38:30 +0530 |
commit | 2a42ad20b9730706ad371ae3787d4597c4e42276 (patch) | |
tree | fa01cd312586ea007468e7233f94c0ce53d75873 /stacks/lwip_stack/src/sbr | |
parent | a826fe833d3f2a8fe2673fa05811fe1a22baf045 (diff) |
Feature: 19.04 part-2DMM-2
Change-Id: I0b52a6bb67c25c7955d58e29eb81a3cc9efea9e9
Signed-off-by: sharath reddy <bs.reddy@huawei.com>
Diffstat (limited to 'stacks/lwip_stack/src/sbr')
-rw-r--r-- | stacks/lwip_stack/src/sbr/CMakeLists.txt | 37 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_err.h | 190 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_index_ring.c | 212 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_index_ring.h | 61 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_protocol_api.h | 102 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_res_mgr.c | 87 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_res_mgr.h | 155 | ||||
-rw-r--r-- | stacks/lwip_stack/src/sbr/sbr_socket.c | 1324 |
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; +} |