diff options
Diffstat (limited to 'src/nSocket')
42 files changed, 8070 insertions, 7238 deletions
diff --git a/src/nSocket/CMakeLists.txt b/src/nSocket/CMakeLists.txt index 5701e8e..ec1f944 100644 --- a/src/nSocket/CMakeLists.txt +++ b/src/nSocket/CMakeLists.txt @@ -14,25 +14,22 @@ # limitations under the License. ######################################################################### - -if(WITH_HAL_LIB) -else() - SET(PAL_H_DIRECTORIES "/usr/include/dpdk/") -endif() - +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") INCLUDE_DIRECTORIES( - include/ - kernel/ - nstack/ - nstack/event/ - nstack/event/epoll - nstack/event/select - ${SECUREC_SRC_H} - ${PAL_H_DIRECTORIES} - ${CMAKE_CURRENT_LIST_DIR}/../adapt - ${CMAKE_CURRENT_LIST_DIR}/../../thirdparty/json/json-c-0.12.1 + ${JSON_C_SRC} + ${CMAKE_CURRENT_LIST_DIR}/include + ${CMAKE_CURRENT_LIST_DIR}/kernel + ${CMAKE_CURRENT_LIST_DIR}/nstack + ${CMAKE_CURRENT_LIST_DIR}/nstack/event/ + ${CMAKE_CURRENT_LIST_DIR}/nstack/event/epoll + ${CMAKE_SOURCE_DIR}/src/framework/event/epoll + ${CMAKE_CURRENT_LIST_DIR}/nstack/event/select + ${CMAKE_SOURCE_DIR}/src/framework/include + ${CMAKE_SOURCE_DIR}/src/framework/include/common/generic + ${CMAKE_SOURCE_DIR}/src/framework/include/common/ + ${CMAKE_SOURCE_DIR}/src/framework/dfx + ${CMAKE_SOURCE_DIR}/src/include ) - FILE(GLOB_RECURSE nSocket *.c) ADD_LIBRARY(nStackAPI SHARED ${nSocket}) TARGET_LINK_LIBRARIES( @@ -40,10 +37,6 @@ TARGET_LINK_LIBRARIES( -Wl,--whole-archive ${LIB_PATH_STATIC}/libjson-c.a ${LIB_PATH_STATIC}/libglog.a - dmm_api - -Wl,--no-whole-archive,-lstdc++ - rte_eal - rte_mempool - rte_mbuf - rte_ring) -ADD_DEPENDENCIES(nStackAPI dmm_api) + nStackFw + -Wl,--no-whole-archive,-lstdc++) +ADD_DEPENDENCIES(nStackAPI nStackFw) diff --git a/src/nSocket/include/declare_syscalls.h b/src/nSocket/include/declare_syscalls.h deleted file mode 100644 index c4810f5..0000000 --- a/src/nSocket/include/declare_syscalls.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -NSTACK_MK_DECL (int, socket, (int, int, int)); -NSTACK_MK_DECL (int, bind, (int, const struct sockaddr *, socklen_t)); -NSTACK_MK_DECL (int, listen, (int, int)); -NSTACK_MK_DECL (int, shutdown, (int, int)); -NSTACK_MK_DECL (int, getsockname, (int, struct sockaddr *, socklen_t *)); -NSTACK_MK_DECL (int, getpeername, (int, struct sockaddr *, socklen_t *)); -NSTACK_MK_DECL (int, getsockopt, (int, int, int, void *, socklen_t *)); -NSTACK_MK_DECL (int, setsockopt, (int, int, int, const void *, socklen_t)); -NSTACK_MK_DECL (int, accept, (int, struct sockaddr *, socklen_t *)); -NSTACK_MK_DECL (int, accept4, - (int, struct sockaddr *, socklen_t *, int flags)); -NSTACK_MK_DECL (int, connect, (int, const struct sockaddr *, socklen_t)); -NSTACK_MK_DECL (ssize_t, recv, (int, void *, size_t, int)); -NSTACK_MK_DECL (ssize_t, send, (int, const void *, size_t, int)); -NSTACK_MK_DECL (ssize_t, read, (int, void *, size_t)); -NSTACK_MK_DECL (ssize_t, write, (int, const void *, size_t)); -NSTACK_MK_DECL (ssize_t, writev, (int, const struct iovec *, int)); -NSTACK_MK_DECL (ssize_t, readv, (int, const struct iovec *, int)); -NSTACK_MK_DECL (ssize_t, sendto, - (int, const void *, size_t, int, const struct sockaddr *, - socklen_t)); -NSTACK_MK_DECL (ssize_t, recvfrom, - (int, void *, size_t, int, struct sockaddr *, socklen_t *)); -NSTACK_MK_DECL (ssize_t, sendmsg, (int, const struct msghdr *, int flags)); -NSTACK_MK_DECL (ssize_t, recvmsg, (int, struct msghdr *, int flags)); -NSTACK_MK_DECL (int, close, (int)); -NSTACK_MK_DECL (int, select, - (int, fd_set *, fd_set *, fd_set *, struct timeval *)); -NSTACK_MK_DECL (int, ioctl, (int, unsigned long, unsigned long)); -NSTACK_MK_DECL (int, fcntl, (int, int, unsigned long)); -NSTACK_MK_DECL (int, epoll_create, (int)); -NSTACK_MK_DECL (int, epoll_ctl, (int, int, int, struct epoll_event *)); -NSTACK_MK_DECL (int, epoll_wait, (int, struct epoll_event *, int, int)); -NSTACK_MK_DECL (pid_t, fork, (void)); -#undef NSTACK_MK_DECL diff --git a/src/nSocket/include/nstack_atomic.h b/src/nSocket/include/nstack_atomic.h index bb5ec13..119002e 100644 --- a/src/nSocket/include/nstack_atomic.h +++ b/src/nSocket/include/nstack_atomic.h @@ -19,7 +19,7 @@ #include <stdio.h> #include <stdlib.h> -#include "nstack_types.h" +#include "types.h" #ifdef __cplusplus /* *INDENT-OFF* */ @@ -29,7 +29,7 @@ extern "C"{ typedef struct { - volatile ns_int32 counter; + volatile ns_int32 counter; } atomic_t; #define atomic_set(v, i) ((v)->counter = (i)) @@ -42,11 +42,11 @@ typedef struct #define atomic_read(v) atomic_fetch_and_add(v, 0) #define atomic_inc(v) atomic_add_and_fetch(v, 1) -#define atomic_dec(v)atomic_sub_and_fetch(v, 1) +#define atomic_dec(v) atomic_sub_and_fetch(v, 1) #define atomic_add(v, i) atomic_add_and_fetch(v, i) #define atomic_sub(v, i) atomic_sub_and_fetch(v,i) -#define cas(ptr, oldValue, exchange) __sync_bool_compare_and_swap(ptr, oldValue, exchange) +#define cas(ptr, oldValue, exchage) __sync_bool_compare_and_swap(ptr, oldValue, exchage) #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/nSocket/include/nstack_dmm_api.h b/src/nSocket/include/nstack_dmm_api.h deleted file mode 100644 index ab06650..0000000 --- a/src/nSocket/include/nstack_dmm_api.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __NSOCKET_DMM_API_H__ -#define __NSOCKET_DMM_API_H__ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/epoll.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "nstack_rd_data.h" - -/* - *Standard api interface definition. - *these interface is provided by Protocol stack to nStack - */ -typedef struct __nstack_socket_ops -{ -#undef NSTACK_MK_DECL -#define NSTACK_MK_DECL(ret, fn, args) ret (*pf##fn) args -#include "declare_syscalls.h" -} nstack_socket_ops; - -typedef enum -{ - STACK_FD_INVALID_CHECK, /*check wether fd is created by this stack */ - STACK_FD_FUNCALL_CHECK, /*check this stack support default call */ -} nstack_fd_check; - -typedef enum -{ - nstack_ep_triggle_add, - nstack_ep_triggle_mod, - nstack_ep_triggle_del -} nstack_ep_triggle_ops_t; - -/* - *Interactive interface for Protocol stack and nStack defined here - *these interface is provided by Protocol stack to nStack - */ -typedef struct __nstack_extern_ops -{ - int (*module_init) (void); /*stack module init */ - int (*module_init_child) (void); /*stack module init for child process */ - int (*fork_init_child) (pid_t p, pid_t c); /*after fork, stack child process init again if needed. */ - void (*fork_parent_fd) (int s, pid_t p); /*after fork, stack parent process proc again if needed. */ - void (*fork_child_fd) (int s, pid_t p, pid_t c); /*after fork, child record pid for recycle if needed. */ - void (*fork_free_fd) (int s, pid_t p, pid_t c); /*for SOCK_CLOEXEC when fork if needed. */ - unsigned int (*ep_ctl) (int epFD, int proFD, int ctl_ops, struct epoll_event * event, void *pdata); /*when fd add to epoll fd, triggle stack to proc if need */ - unsigned int (*ep_getevt) (int epFD, int profd, unsigned int events); /*check whether some events exist really */ - int (*ep_prewait_proc) (int epfd); - int (*stack_fd_check) (int s, int flag); /*check whether fd belong to stack, if belong, return 1, else return 0 */ - int (*stack_alloc_fd) (); /*alloc a fd id for epoll */ - int (*peak) (int s); /*used for stack-x , isource maybe no need */ -} nstack_extern_ops; - -/* - *The event notify interface provided to the protocol stack by nStack - *these interface is provided by nStack to Protocol stack - */ -typedef struct __nstack_event_cb -{ - void *handle; /*current so file handler */ - int type; /*nstack is assigned to the protocol stack and needs to be passed to nstack when the event is reported */ - int (*event_cb) (void *pdata, int events); -} nstack_event_cb; - -typedef struct __nstack_proc_cb -{ - nstack_socket_ops socket_ops; /*posix socket api */ - nstack_extern_ops extern_ops; /*other proc callback */ -} nstack_proc_cb; - -typedef int (*nstack_stack_register_fn) (nstack_proc_cb * proc_fun, - nstack_event_cb * event_ops); - -#endif diff --git a/src/nSocket/include/nstack_eventpoll.h b/src/nSocket/include/nstack_eventpoll.h deleted file mode 100644 index afb0b05..0000000 --- a/src/nSocket/include/nstack_eventpoll.h +++ /dev/null @@ -1,338 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _NSTACK_EVENTPOOL_H -#define _NSTACK_EVENTPOOL_H - -#include "ephlist.h" -#include "eprb_tree.h" -#include "common_mem_api.h" -#include "types.h" -#include <semaphore.h> -#include <sys/epoll.h> -#include <stdio.h> -#include <stdlib.h> -#include "nstack_securec.h" -#include "nstack_log.h" - -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C"{ -/* *INDENT-ON* */ -#endif /* __cplusplus */ - -#define NSTACK_MAX_EPOLL_INFO_NUM 8192 -#define NSTACK_MAX_EPOLL_NUM NSTACK_MAX_EPOLL_INFO_NUM -#define NSTACK_MAX_EPITEM_NUM (NSTACK_MAX_EPOLL_NUM*2) - -#define MP_NSTACK_EPOLL_INFO_NAME "nsep_info" -#define MP_NSTACK_EVENTPOLL_POOL "nsep_eventpoll" /* Pool of struct eventpoll */ -#define MP_NSTACK_EPITEM_POOL "nsep_epitem" /* Pool of struct epitem */ - -#define MP_NSTACK_EPINFO_RING_NAME "nsep_info_ring" -#define MP_NSTACK_EPITEM_RING_NAME "nsep_item_ring" -#define MP_NSTACK_EVENTPOOL_RING_NAME "nsep_event_ring" - -#define NSTACK_FORK_NUM 32 -#define NSTACK_EPOL_FD 1 - -#define NSEP_SMOD_MAX 8 - -#define NSEP_EP_UNACTIVE_PTR ((void *) -1L) - -COMPAT_PROTECT (NSEP_SMOD_MAX, 8); - -typedef struct -{ - u32 pid_used_size; - u32 pid_array[NSTACK_FORK_NUM]; -} nsep_pidinfo; - -struct eventpoll -{ - - /* - * Protect the this structure access - * This is for event add to ready list and poll out - */ - sys_sem_st lock; - - /* - * This semaphore is used to ensure that files are not removed - * while epoll is using them. This is read-held during the event - * processing loop and it is write-held during the file cleanup - * path, the epoll file exit code and the ctl operations. - * When we do epoll_ctl, we write lock - * When we collecting data , we read lock - */ - sys_sem_st sem; - - /* - * This semaphore is used to block epoll_wait function - */ - sem_t waitSem; - - /* List of ready file descriptors */ - struct ep_hlist rdlist; - - /* When poll data out, we need this list to store tmp epitems */ - struct epitem *ovflist; - - /* RB-Tree root used to store mastered fd structs */ - struct ep_rb_root rbr; - - /* This specifies the file descriptor value of epoll instance, currenlty it is just used for debugging */ - int epfd; - u32 pid; - nsfw_res res_chk; -}; - -struct eventpoll_pool -{ - void *ring; - struct eventpoll *pool; -}; - -typedef struct -{ - int iindex; - int iNext; - int fd; - i32 epaddflag; - i32 fdtype; /*0: socket fd, 1: epoll fd */ - i32 rlfd; /* copy of fdInf->rlfd */ - i32 rmidx; /* copy of fdInf->rmidx */ - i32 protoFD[NSEP_SMOD_MAX]; /* copy of fdInf->protoFD */// Here we need to set router infomations dependency - struct eventpoll *ep; - sys_sem_st epiLock; - sys_sem_st freeLock; - struct ep_list epiList; /* This restore the epitem of this file descriptor */ - u32 sleepTime; //add for NSTACK_SEM_SLEEP - nsep_pidinfo pidinfo; - nsfw_res res_chk; - void *private_data; /*add for debug, just used to record extern infomation, for example sbr conn */ - i32 reserv[4]; -} nsep_epollInfo_t; - -typedef struct -{ - void *ring; - nsep_epollInfo_t *pool; - char last_reserve[8]; //reserve for update -} nsep_infoPool_t; - -struct epitem -{ - struct ep_rb_node rbn; - struct ep_hlist_node rdllink; - struct ep_hlist_node lkFDllink; - int nwait; - struct eventpoll *ep; - nsep_epollInfo_t *epInfo; - struct epitem *next; - struct epoll_event event; - struct list_node fllink; - unsigned int revents; - unsigned int ovf_revents; - int fd; - u32 pid; - void *private_data; - nsfw_res res_chk; -}; - -struct epitem_pool -{ - void *ring; - struct epitem *pool; -}; - -typedef struct -{ - struct eventpoll_pool epollPool; - struct epitem_pool epitemPool; - nsep_infoPool_t infoPool; - nsep_epollInfo_t **infoSockMap; // The map of epInfo and socket - -} nsep_epollManager_t; -extern nsep_epollManager_t g_epollMng; -#define nsep_getManager() (&g_epollMng) - -extern int nsep_alloc_eventpoll (struct eventpoll **data); -extern int nsep_free_eventpoll (struct eventpoll *ep); -extern int nsep_alloc_epitem (struct epitem **data); -extern int nsep_free_epitem (struct epitem *data); -extern int nsep_alloc_epinfo (nsep_epollInfo_t ** data); -extern int nsep_free_epinfo (nsep_epollInfo_t * info); - -extern int nsep_epitem_remove (nsep_epollInfo_t * pinfo, u32 pid); - -extern struct epitem *nsep_find_ep (struct eventpoll *ep, int fd); -extern int nsep_epctl_add (struct eventpoll *ep, int fd, - struct epoll_event *events); -extern int nsep_epctl_del (struct eventpoll *ep, struct epitem *epi); -extern int nsep_epctl_mod (struct eventpoll *ep, - nsep_epollInfo_t * epInfo, - struct epitem *epi, struct epoll_event *events); -extern int nsep_ep_poll (struct eventpoll *ep, struct epoll_event *events, - int maxevents, int *eventflag, int num); -extern void nsep_remove_epfd (nsep_epollInfo_t * info); -extern void nsep_close_epfd (struct eventpoll *ep); - -/** - * @Function nsep_init_infoSockMap - * @Description initial map of epoll info and socket - * @param none - * @return 0 on success, -1 on error - */ -extern int nsep_init_infoSockMap (); -extern void nsep_set_infoSockMap (int sock, nsep_epollInfo_t * info); -extern nsep_epollInfo_t *nsep_get_infoBySock (int sock); -extern int nsep_alloc_infoWithSock (int nfd); -extern void nsep_set_infoProtoFD (int fd, int modInx, int protoFD); -extern int nsep_get_infoProtoFD (int fd, int modInx); -extern void nsep_set_infomdix (int fd, int rmidx); -extern int nsep_get_infoMidx (int fd); -extern void nsep_set_infoRlfd (int fd, int rlfd); -extern int nsep_get_infoRlfd (int fd); -extern void nsep_set_infoSleepTime (int fd, u32 sleepTime); -extern int nsep_get_infoSleepTime (int fd); -extern void nsep_set_infoEp (int fd, struct eventpoll *ep); -extern struct eventpoll *nsep_get_infoEp (int fd); -extern int nsep_free_infoWithSock (int sock); -extern int nstack_ep_unlink (struct eventpoll *ep, struct epitem *epi); - -/* Attach shared memory */ -extern int nsep_create_memory (); -extern int nsep_attach_memory (); -extern int nsep_ep_fdinfo_release (int sock); -extern int nsep_epoll_close (int sock); -extern void nsep_fork_child_proc (u32_t ppid); -extern void nsep_fork_parent_proc (u32_t ppid, u32_t cpid); - -static inline i32 -nsep_for_pidinfo_init (nsep_pidinfo * pidinfo) -{ - int ret; - ret = MEMSET_S (pidinfo, sizeof (*pidinfo), 0, sizeof (*pidinfo)); - if (EOK != ret) - { - NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); - return -1; - } - return 0; -} - -static inline int -nsep_add_pid (nsep_pidinfo * pidinfo, pid_t pid) -{ - int i; - - for (i = 0; i < NSTACK_FORK_NUM; i++) - { - if ((0 == pidinfo->pid_array[i]) - && (__sync_bool_compare_and_swap (&pidinfo->pid_array[i], 0, pid))) - { - if (pidinfo->pid_used_size < i + 1) - { - pidinfo->pid_used_size = i + 1; - } - return 0; - } - } - return -1; -} - -static inline int -nsep_del_pid (nsep_pidinfo * pidinfo, pid_t pid) -{ - int i; - - for (i = 0; i < pidinfo->pid_used_size && i < NSTACK_FORK_NUM; i++) - { - if (pid == pidinfo->pid_array[i]) - { - pidinfo->pid_array[i] = 0; - return 0; - } - } - return -1; -} - -static inline int -nsep_del_last_pid (nsep_pidinfo * pidinfo, pid_t pid) -{ - int i; - int count = 0; - int deleted = 0; - for (i = 0; i < pidinfo->pid_used_size && i < NSTACK_FORK_NUM; i++) - { - if (pid == pidinfo->pid_array[i]) - { - pidinfo->pid_array[i] = 0; - deleted = 1; - continue; - } - - if (pidinfo->pid_array[i] != 0) - { - ++count; - } - } - - if (!deleted) - { - return -1; - } - - return count; -} - -static inline int -nsep_is_pid_exist (nsep_pidinfo * epinf, pid_t pid) -{ - int i; - - for (i = 0; i < epinf->pid_used_size && i < NSTACK_FORK_NUM; i++) - { - if (pid == epinf->pid_array[i]) - { - return 1; - } - } - return 0; -} - -static inline int -nsep_is_pid_array_empty (nsep_pidinfo * epinf) -{ - int i; - for (i = 0; i < epinf->pid_used_size && i < NSTACK_FORK_NUM; i++) - { - if (epinf->pid_array[i] != 0) - { - return 0; - } - } - return 1; -} - -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif /* __cplusplus */ - -#endif /* _NSTACK_EVENTPOLL_H */ diff --git a/src/nSocket/include/nstack_ip_addr.h b/src/nSocket/include/nstack_ip_addr.h deleted file mode 100644 index 8b15854..0000000 --- a/src/nSocket/include/nstack_ip_addr.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __NSTACK_IP_ADDR_H__ -#define __NSTACK_IP_ADDR_H__ - -#ifndef ip4_addr1_16 -#include "nstack_types.h" - -/* Get one byte from the 4-byte address */ -#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) /* ip4_addr1(ipaddr) */ -#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) /* ip4_addr2(ipaddr) */ -#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) /* ip4_addr3(ipaddr) */ -#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) /* ip4_addr4(ipaddr) */ - -/* These are cast to u16_t, with the intent that they are often arguments - * to printf using the U16_F format from cc.h. */ -#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) /*ip4_addr1_16(ipaddr) */ -#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) /*ip4_addr2_16(ipaddr) */ -#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) /*ip4_addr3_16(ipaddr) */ -#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) /*ip4_addr4_16(ipaddr) */ -#endif -#endif diff --git a/src/nSocket/include/nstack_rd.h b/src/nSocket/include/nstack_rd.h index a93f6a6..0df64b2 100644 --- a/src/nSocket/include/nstack_rd.h +++ b/src/nSocket/include/nstack_rd.h @@ -17,31 +17,38 @@ #ifndef __NSTACK_RD_H #define __NSTACK_RD_H +#include <sys/socket.h> +#include <netinet/in.h> +#include "nstack_rd_priv.h" + /*look up chose info by key*/ typedef struct __nstack_rd_key { - int type; - union - { - unsigned int ip_addr; - unsigned int proto_type; - }; + int type; + union + { + unsigned int ip_addr; + int socket_type; + int proto; + struct in6_addr in6_addr; + }; } nstack_rd_key; -#define NSTACK_RD_MAX (1 * 1024 * 1024) - /* *rd synchronism * */ -int nstack_rd_sys (); -int nstack_rd_age (); +int nstack_rd_init(nstack_rd_stack_info * pstack, int num); +int nstack_rd_sys(); +int nstack_rd_age(); +int nstack_rd_match_pre(int domain, int type, int protocol, + rd_data_item * item); /* *get stackid by some info *if input is ip, the value must be net order * */ -int nstack_rd_get_stackid (nstack_rd_key * addr, int *stackid); +int nstack_rd_get_stackid(nstack_rd_key * addr, rd_data_item * item); #endif diff --git a/src/nSocket/include/nstack_rd_init.h b/src/nSocket/include/nstack_rd_init.h deleted file mode 100644 index a8b2e9e..0000000 --- a/src/nSocket/include/nstack_rd_init.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _NSTACK_RD_INIT_H_ -#define _NSTACK_RD_INIT_H_ -#include "nstack_rd_data.h" - -#define NSTACK_RD_CHECK_BELONG (1) -#define NSTACK_RD_CHECK_NOT_BELONG (0) - -typedef struct __nstack_stack_info -{ - /*stack name */ - char name[STACK_NAME_MAX]; - /*stack id */ - int stack_id; - /*when route info not found, high priority stack was chose, same priority chose fist input one */ - int priority; /*0: highest: route info not found choose first */ -} nstack_stack_info; - -/*get rd info. if return ok, data callee alloc memory, caller free, else caller don't free*/ -typedef int (*nstack_get_route_data) (rd_route_data ** data, int *num); - -/* - *rd init - *default id: if all module check fail, just return default id - *return : 0 success, -1 fail - */ -int nstack_rd_init (nstack_stack_info * pstack, int num, - nstack_get_route_data * pfun, int fun_num); - -#endif diff --git a/src/nSocket/nstack_rd/nstack_rd_priv.h b/src/nSocket/include/nstack_rd_priv.h index 7179364..4069571 100644 --- a/src/nSocket/nstack_rd/nstack_rd_priv.h +++ b/src/nSocket/include/nstack_rd_priv.h @@ -17,17 +17,16 @@ #ifndef __NSTACK_RD_PRIV_H #define __NSTACK_RD_PRIV_H #include "list.h" +#include "nstack_rd_data.h" #define NSTACK_RD_SUCCESS (0) #define NSTACK_RD_FAIL (-1) #define NSTACK_RD_ITEM_MAX (1024) #define NSTACK_RD_AGETIME_MAX (1) -#define NSTACK_SYS_FUN_MAX (16) - -#define RD_LWIP "lwip" -#define RD_KERNEL "kernel" +#define RD_STACKPOOL_NAME "stackpool" +#define RD_KERNEL_NAME "kernel" #define NSTACK_RD_INDEX_BYIP(ip) (((ip) & 0xff) \ + (((ip) >> 8)&0xff) \ + (((ip) >> 16)&0xff) \ @@ -36,57 +35,64 @@ /*route data*/ typedef struct __rd_data_item { - /*route info type , for example base on ip */ - rd_data_type type; - int stack_id; - int agetime; - union - { - rd_ip_data ipdata; - unsigned int proto_type; - }; + /*route info type , for example base on ip */ + rd_data_type type; + int stack_id; + int agetime; + union + { + rd_ip_data ipdata; + rd_type_data type_data; + rd_proto_data proto_data; + rd_ip6_data ip6data; + }; } rd_data_item; /*stack rd node*/ typedef struct __nstack_rd_node { - struct hlist_node rdnode; - rd_data_item item; + struct hlist_node rdnode; + rd_data_item item; } nstack_rd_node; typedef struct __nstack_rd_list { - struct hlist_head headlist; + struct hlist_head headlist; } nstack_rd_list; typedef struct __nstack_rd_stack_info { - /*stack name */ - char name[STACK_NAME_MAX]; - /*stack id */ - int stack_id; - /*when route info not found, high priority stack was chose, same priority chose fist input one */ - int priority; /*0: highest: route info not found choose first */ + /*stack name */ + char name[STACK_NAME_MAX]; + /*stack id */ + int stack_id; + /*when route info not found, high priority stack was chose, same priority chose fist input one */ + int priority; /*0: highest: route info not found choose first */ } nstack_rd_stack_info; +typedef int (*nstack_get_route_data) (rd_route_data ** data, int *num, + int *ver, rd_route_table * handle); +typedef int (*nstack_get_rdtble_ver) (int *ver, rd_route_table * handle); + /*rd local data*/ typedef struct __rd_local_data { - nstack_rd_stack_info *pstack_info; - int stack_num; - nstack_rd_list route_list[RD_DATA_TYPE_MAX]; /*route table */ - nstack_get_route_data sys_fun[NSTACK_SYS_FUN_MAX]; /*rd data sys proc function list */ - int fun_num; + int *rdlocal_ver; + nstack_rd_stack_info *pstack_info; + int stack_num; + nstack_rd_list route_list[RD_DATA_TYPE_MAX]; /*route table */ + nstack_get_route_data sys_fun; + nstack_get_rdtble_ver rdtbl_ver_get_fun; } rd_local_data; typedef struct __rd_data_proc { - int (*rd_item_cpy) (void *destdata, void *srcdata); - int (*rd_item_inset) (nstack_rd_list * hlist, void *rditem); - int (*rd_item_age) (nstack_rd_list * hlist); - int (*rd_item_find) (nstack_rd_list * hlist, void *rdkey, void *outitem); - int (*rd_item_spec) (void *rdkey); - int (*rd_item_default) (void *rdkey); + int (*rd_item_copy) (void *destdata, void *srcdata); + int (*rd_item_insert) (nstack_rd_list * hlist, void *rditem); + int (*rd_item_age) (nstack_rd_list * hlist); + void (*rd_item_clean) (nstack_rd_list * hlist); + int (*rd_item_find) (nstack_rd_list * hlist, void *rdkey, void *outitem); + int (*rd_item_spec) (void *rdkey); } rd_data_proc; extern rd_local_data *g_rd_local_data; @@ -96,6 +102,4 @@ extern rd_data_proc g_rd_cpy[RD_DATA_TYPE_MAX]; #define NSTACK_RD_LIST(type) (&(g_rd_local_data->route_list[(type)])) #define NSTACK_GET_STACK(idx) ((g_rd_local_data->pstack_info)[idx].stack_id) -int nstack_get_stackid_byname (char *name); - #endif diff --git a/src/nSocket/include/nstack_select.h b/src/nSocket/include/nstack_select.h index 659c477..6c67c95 100644 --- a/src/nSocket/include/nstack_select.h +++ b/src/nSocket/include/nstack_select.h @@ -14,22 +14,6 @@ * limitations under the License. */ -/*==============================================* - * include header files * - *----------------------------------------------*/ - -/*==============================================* - * constants or macros define * - *----------------------------------------------*/ - -/*==============================================* - * project-wide global variables * - *----------------------------------------------*/ - -/*==============================================* - * routines' or functions' implementations * - *----------------------------------------------*/ - #define NSTACK_SELECT_MODULE #ifdef NSTACK_SELECT_MODULE @@ -37,6 +21,7 @@ #ifndef __NSTACK_SELECT_H__ #define __NSTACK_SELECT_H__ +/* move include files outside the extern C */ #include <sys/types.h> #include <sys/time.h> #include <stdio.h> @@ -49,101 +34,153 @@ extern "C" { /* *INDENT-ON* */ #endif -typedef int (*get_select_event) (int nfds, fd_set * readfd, - fd_set * writefd, fd_set * exceptfd, - struct timeval * timeout); +typedef int (*get_select_event) (int nfds, fd_set * readfd, fd_set * writefd, + fd_set * exceptfd, struct timeval * timeout); typedef struct { - unsigned char fds_bits[(NSTACK_SETSIZE + 7) >> 3]; + unsigned char *fds_bits; // (NSTACK_SETSIZE+7)>>3 } __attribute__ ((packed)) nstack_fd_set; -#define NSTACK_FD_SET(n, p) ((p)->fds_bits[(n)>>3]|=1U<<((n)&0x07)) -#define NSTACK_FD_ISSET(n,p) (((p)->fds_bits[(n)>>3]&(1U<<((n)&0x07)))?1:0) -#define NSTACK_FD_CLR(n,p) ((p)->fds_bits[(n)>>3]&=~(1U<<((n)&0x07))) -#define NSTACK_FD_ZERO(p) (MEMSET_S((void *)(p), sizeof(*(p)),0,sizeof(*(p)))) +#define NSTACK_FD_SET(n, p) ((p)->fds_bits[(n)>>3]|=1U<<((n)&0x07)) +#define NSTACK_FD_ISSET(n,p) (((p)->fds_bits[(n)>>3]&(1U<<((n)&0x07)))?1:0) +#define NSTACK_FD_CLR(n,p) ((p)->fds_bits[(n)>>3]&=~(1U<<((n)&0x07))) +#define NSTACK_FD_ZERO(p, mem_size) (memset_s((void *)(p->fds_bits), mem_size,0,mem_size)) #define NSTACK_FD_OR(p1 ,p2) {\ int i;\ - for(i = 0; i < (NSTACK_SETSIZE+7)>>3; i++){\ + for(i = 0; i < (NSTACK_SELECT_MAX_FD+7)>>3; i++){\ (p1)->fds_bits[i] |= (p2)->fds_bits[i];\ }\ } struct select_cb_p { - union - { nstack_fd_set nstack_readset; - fd_set readset; - }; - union - { nstack_fd_set nstack_writeset; - fd_set writeset; - }; - union - { nstack_fd_set nstack_exceptset; + + fd_set readset; + fd_set writeset; fd_set exceptset; - }; - union - { - i32 count; - i32 readyset; - }; + union + { + i32 count; + i32 readyset; + }; - i32 inx; - i32 select_errno; + i32 inx; + i32 select_errno; }; struct select_entry_info { - i32 set_num; //how many select_c_p is set - i32 index; //the first cb was set + i32 set_num; //how many select_c_p is set + i32 index; //the frist cb was set }; struct select_entry { - struct select_cb_p cb[NSTACK_MAX_MODULE_NUM]; - struct select_cb_p ready; - struct select_entry *next; - struct select_entry *prev; - struct select_entry_info info; - select_sem_t sem; + struct select_cb_p cb[NSTACK_MAX_MODULE_NUM]; + struct select_cb_p ready; + struct select_entry *next; + struct select_entry *prev; + struct select_entry_info info; + select_sem_t sem; }; struct select_module_info { - struct select_entry *entry_head; - struct select_entry *entry_tail; - get_select_event get_select_fun_nonblock[NSTACK_MAX_MODULE_NUM]; - get_select_event get_select_fun_block[NSTACK_MAX_MODULE_NUM]; - get_select_event default_fun; - i32 default_mod; - volatile i32 inited; - select_spinlock_t lock; - select_sem_t sem; + struct select_entry *entry_head; + struct select_entry *entry_tail; + get_select_event get_select_fun_nonblock[NSTACK_MAX_MODULE_NUM]; + get_select_event get_select_fun_block[NSTACK_MAX_MODULE_NUM]; + get_select_event default_fun; + i32 default_mod; + volatile i32 inited; + select_spinlock_t lock; + select_sem_t sem; }; -extern i32 select_cb_split_by_mod (i32 nfds, - fd_set * readfd, - fd_set * writefd, - fd_set * exceptfd, - struct select_entry *entry); -extern void entry_module_fdset (struct select_entry *entry, - i32 fd_size, - nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, i32 inx); -extern i32 select_scan (struct select_entry *entry); -extern i32 select_add_cb (struct select_entry *entry); -extern i32 select_rm_cb (struct select_entry *entry); -extern i32 select_entry_reset (struct select_entry *entry); -extern i32 select_module_init (); -extern i32 select_module_init_child (); - -extern struct select_module_info *get_select_module (void); +extern i32 select_cb_split_by_mod(i32 nfds, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, + struct select_entry *entry); +extern void entry_module_fdset(struct select_entry *entry, + i32 fd_size, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, i32 inx); + +extern int nstack_select_processing(int nfds, + fd_set * readfds, + fd_set * writefds, + fd_set * exceptfds, + struct timeval *timeout); +extern i32 select_scan(struct select_entry *entry); +extern i32 select_add_cb(struct select_entry *entry); +extern i32 select_rm_cb(struct select_entry *entry); +extern i32 select_entry_reset(struct select_entry *entry); +extern i32 select_module_init(); +extern struct select_module_info *get_select_module(void); + +#define NS_FD_ISSET(fd,set) ((set) &&(FD_ISSET(fd,set))) +#define NFDS_NOT_VALID(nfds) (((nfds)>__FD_SETSIZE)||((nfds)<0)) +#define TIMEVAL_NOT_VALID(time) ((time)&&(((time)->tv_sec<0)||((time)->tv_usec<0))) +#define TIMEVAL_EQUAL_ZERO(time) ((time)&&(((time)->tv_sec==0)&&((time)->tv_usec==0))) +static inline void print_select_dbg(int nfds, fd_set * readfds, + fd_set * writefds, fd_set * exceptfds) +{ + int i; + for (i = 0; i < nfds; i++) + { + + if (NS_FD_ISSET(i, readfds)) + { + NSSOC_LOGDBG("input readfd set=%d", i); + } + if (NS_FD_ISSET(i, writefds)) + { + NSSOC_LOGDBG("input writefd set=%d", i); + } + if (NS_FD_ISSET(i, exceptfds)) + { + NSSOC_LOGDBG("input exceptfds set=%d", i); + } + + } +} + +static inline bool is_select_used_as_timer(int nfds, fd_set * readfds, + fd_set * writefds, + fd_set * exceptfds) +{ + return ((nfds <= 0) + || ((NULL == readfds) && (NULL == writefds) + && (NULL == exceptfds))); +} + +static inline void *select_fd_set_bits_alloc() +{ + void *addr; + addr = + select_alloc(sizeof(unsigned char) * + ((NSTACK_SELECT_MAX_FD + 7) >> 3)); + return addr; +} + +static inline void select_fd_set_free(nstack_fd_set * addr) +{ + select_free(addr); +} + +#define FREE_SELECT_FD_SET(readfd, writefd, exceptfd) {\ + select_free(readfd);\ + select_free(writefd);\ + select_free(exceptfd);\ +} + #ifdef __cplusplus /* *INDENT-OFF* */ } diff --git a/src/nSocket/include/nstack_sockops.h b/src/nSocket/include/nstack_sockops.h index 63fefee..3d86559 100644 --- a/src/nSocket/include/nstack_sockops.h +++ b/src/nSocket/include/nstack_sockops.h @@ -27,16 +27,19 @@ extern "C"{ #define NSTACK_CAL_FUN(ops, fun, args, retval) \ {\ + /* reset retval before invoke api */ \ + retval = -1;\ if(NULL != (ops) && NULL != (ops)->pf##fun)\ {\ if((retval = ((ops)->pf##fun args)) == -1)\ {\ - NSSOC_LOGDBG("function=%s execute failed,ret=%d.errno=%d.", #fun, retval, errno); \ + NSSOC_LOGDBG("function excute failed] func=%s,ret=%d,errno=%d.", #fun, retval, errno); \ }\ }\ else\ {\ - NSSOC_LOGERR("NULL address erro, ops_pointer=%p,function=%s", (ops), #fun); \ + /* the error info when it works well */ \ + NSSOC_LOGDBG("NSTACK_CAL_FUN NULL] ops_pointer=%p,function=%s", (ops), #fun); \ errno = EBADF; \ }\ } diff --git a/src/nSocket/include/nstack_types.h b/src/nSocket/include/nstack_types.h deleted file mode 100644 index 90b538e..0000000 --- a/src/nSocket/include/nstack_types.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _NSTACK_TYPES_H_ -#define _NSTACK_TYPES_H_ -#include <semaphore.h> -#include <time.h> -#include <stdint.h> -#include <stdlib.h> -#include <common_pal_bitwide_adjust.h> - -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C"{ -/* *INDENT-ON* */ -#endif - -#ifndef NSTACK_MAX_U32_NUM -#define NSTACK_MAX_U32_NUM ((u32_t)0xffffffff) -#endif - -#ifndef NSTACK_MAX_S32_NUM -#define NSTACK_MAX_S32_NUM ((s32_t)0x7fffffff) -#endif - -#ifndef NSTACK_MAX_U64_NUM -#define NSTACK_MAX_U64_NUM ((u64_t)0xffffffffffffffff) -#endif - -#ifndef NSTACK_MAX_S64_NUM -#define NSTACK_MAX_S64_NUM ((s64_t)0x7fffffffffffffff) -#endif - -typedef uint64_t u64_t; -typedef int64_t s64_t; - -typedef uint32_t u32_t; -typedef int32_t s32_t; - -typedef uint16_t u16_t; -typedef int16_t s16_t; - -typedef uint8_t u8_t; -typedef int8_t s8_t; - -typedef uintptr_t mem_ptr_t; - -typedef s8_t err_t; - -#define ERR_OK 0 /* No error, everything OK. */ -#define ERR_MEM -1 /* Out of memory error. */ - -#ifndef ns_bool -typedef unsigned char ns_bool; -#endif - -#ifndef ns_false -#define ns_false 0 -#endif - -#ifndef ns_true -#define ns_true 1 -#endif - -#ifndef ns_success -#define ns_success 0 -#endif - -#ifndef ns_fail -#define ns_fail -1 -#endif - -#ifndef ns_static -#define ns_static static -#endif - -#ifndef ns_uint32 -typedef unsigned int ns_uint32; -#endif - -#ifndef ns_int32 -typedef signed int ns_int32; -#endif - -#ifndef ns_char -typedef char ns_char; -#endif - -#ifndef ns_uchar -typedef unsigned char ns_uchar; -#endif - -#ifndef ns_int8 -typedef signed char ns_int8; -#endif - -#ifndef ns_uint8 -typedef unsigned char ns_uint8; -#endif - -#ifndef ns_uint16 -typedef unsigned short ns_uint16; -#endif - -#ifndef ns_int16 -typedef signed short ns_int16; -#endif - -#ifndef ns_uint -typedef unsigned int ns_uint; -#endif - -#ifndef ns_int -typedef signed int ns_int; -#endif - -#ifndef ns_ullong -typedef unsigned long long ns_ullong; -#endif - -#ifndef ns_llong -typedef long long ns_llong; -#endif - -#ifdef ns_slong -typedef signed long ns_slong; -#endif - -#ifdef ns_ulong -typedef unsigned long ns_ulong; -#endif - -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif - -#endif /* _NSTACK_TYPES_H_ */ diff --git a/src/nSocket/include/select_adapt.h b/src/nSocket/include/select_adapt.h index 2898c76..b655cf8 100644 --- a/src/nSocket/include/select_adapt.h +++ b/src/nSocket/include/select_adapt.h @@ -14,51 +14,23 @@ * limitations under the License. */ -/*==============================================* - * include header files * - *----------------------------------------------*/ - -/*==============================================* - * constants or macros define * - *----------------------------------------------*/ - -/*==============================================* - * project-wide global variables * - *----------------------------------------------*/ - -/*==============================================* - * routines' or functions' implementations * - *----------------------------------------------*/ - #ifndef __SELECT_ADAPT_H__ #define __SELECT_ADAPT_H__ #include "types.h" #include "nstack_module.h" -#include "common_mem_spinlock.h" #include "nstack_securec.h" -#include "common_func.h" - -#define SBR_MAX_FD_NUM MAX_SOCKET_NUM - -#define NSTACK_SELECT_MAX_FD 8192 -#define NSTACK_SETSIZE 8192 +#include "dmm_spinlock.h" +#include "nsfw_maintain_api.h" -#define FREE_FD_SET(readfd, writefd, exceptfd) {\ - if(readfd)\ - free(readfd);\ - if(writefd)\ - free(writefd);\ - if(exceptfd)\ - free(exceptfd);\ -} +#define NSTACK_SELECT_MAX_FD MAX_SOCKET_NUM //CFG(CFG_MAX_SOCKET_NUM) typedef sem_t select_sem_t; -typedef common_mem_spinlock_t select_spinlock_t; +typedef dmm_spinlock_t select_spinlock_t; -#define select_spin_lock(lock) (common_mem_spinlock_lock((lock))) -#define select_spin_unlock(lock) (common_mem_spinlock_unlock((lock))) -#define select_spin_lock_init(lock) (common_mem_spinlock_init((lock))) +#define select_spin_lock(lock) (dmm_spin_lock((lock))) +#define select_spin_unlock(lock) (dmm_spin_unlock((lock))) +#define select_spin_lock_init(lock) (dmm_spin_init((lock))) #define select_sem_wait(sem) (sem_wait((sem))) #define select_sem_init(sem, share, val) (sem_init((sem), (share), (val))) @@ -66,40 +38,38 @@ typedef common_mem_spinlock_t select_spinlock_t; /*************input form other modules***************************/ extern nstack_module_info g_nstack_modules; -#define get_mode_num() (g_nstack_modules.modNum) -#define get_mode_linux_index() (g_nstack_modules.fix_mid) struct select_comm_fd_map { - i32 mod_fd[NSTACK_MAX_MODULE_NUM]; //save modules fd - i32 index; //-1 mean not select modules + i32 mod_fd[NSTACK_MAX_MODULE_NUM]; //save modules fd + i32 index; //-1 mean not select modules }; struct select_mod_fd_map { - i32 *comm_fd; //the fd app used + i32 *comm_fd; //the fd app used }; struct select_fd_map_inf { - struct select_comm_fd_map *fdinf; //NSTACK_MAX_SOCK_NUM - struct select_mod_fd_map modinf[NSTACK_MAX_MODULE_NUM]; + struct select_comm_fd_map *fdinf; //NSTACK_MAX_SOCK_NUM + struct select_mod_fd_map modinf[NSTACK_MAX_MODULE_NUM]; }; -void *select_alloc (int size); -void select_free (char *p); -void reset_select_fdinf (i32 fd); -i32 select_get_modfd (i32 fd, i32 inx); -i32 select_set_modfd (i32 fd, i32 inx, i32 modfd); -i32 select_get_modindex (i32 fd); -i32 select_get_commfd (i32 modfd, i32 inx); -i32 select_set_commfd (i32 modfd, i32 inx, i32 fd); -i32 fdmapping_init (void); -i32 select_set_index (i32 fd, i32 inx); -i32 select_set_profd (i32 fd, i32 profd); -void nssct_close (i32 cfd, i32 inx); -void nssct_create (i32 cfd, i32 mfd, i32 inx); -void nssct_set_index (i32 fd, i32 inx); +void *select_alloc(int size); +void select_free(void *p); +void reset_select_fdinf(i32 fd); +i32 select_get_modfd(i32 fd, i32 inx); +i32 select_set_modfd(i32 fd, i32 inx, i32 modfd); +i32 select_get_modindex(i32 fd); +i32 select_get_commfd(i32 modfd, i32 inx); +i32 select_set_commfd(i32 modfd, i32 inx, i32 fd); +i32 fdmapping_init(void); +i32 select_set_index(i32 fd, i32 inx); +i32 select_set_profd(i32 fd, i32 profd); +void nssct_close(i32 cfd, i32 inx); +void nssct_create(i32 cfd, i32 mfd, i32 inx); +void nssct_set_index(i32 fd, i32 inx); #endif diff --git a/src/nSocket/kernel/linux_kernel_module.c b/src/nSocket/kernel/linux_kernel_module.c index eb3dd8d..71371bb 100644 --- a/src/nSocket/kernel/linux_kernel_module.c +++ b/src/nSocket/kernel/linux_kernel_module.c @@ -24,310 +24,313 @@ #include<unistd.h> #include <string.h> #include <pthread.h> -#include "nstack_types.h" +#include "types.h" #include "nstack_sockops.h" #include "nstack_log.h" #include "linux_kernel_module.h" #include "linux_kernel_socket.h" #include "nsfw_base_linux_api.h" #include "nstack_fd_mng.h" -#include "nstack_dmm_api.h" +#include "nstack_epoll_api.h" +#include "dmm_spinlock.h" +#include "nsfw_mem_api.h" +#include "nstack_info_parse.h" +#include "nstack_eventpoll.h" +#include "nstack_rd_api.h" #define SK_MAX_EP_EVENT 1024 -kernel_stack_info_t g_ksInfo = {.thread_inited = ks_false,.epfd = - -1,.checkEpollFD = -1 -}; +void *krd_table = NULL; +kernel_stack_info_t g_ksInfo = {.thread_inited = ks_false }; /*design ensures that g_ksInfo is not write accessed at the same time. only read is done simultaneously with no chance of other thread writing it. so no protection needed.*/ -/* Custodial pointer not freed for events at end of this function */ -/* This can be ignored as this is a thread and runs in infinite loop. Hence will never return */ -void * -ks_ep_thread (void *arg) + +/*no need to free these points because the function is always running */ +/*point is set to NULL because it's freeed */ +void *ks_ep_thread(void *arg) { - int eventNum = 0; - int loop = 0; - struct epoll_event *events = - (struct epoll_event *) malloc (SK_MAX_EP_EVENT * - sizeof (struct epoll_event)); - struct epoll_event *innerEvt = - (struct epoll_event *) malloc (SK_MAX_EP_EVENT * - sizeof (struct epoll_event)); - - if (NULL == events || NULL == innerEvt) + int eventNum = 0; + int loop = 0; + int retval = 0; + int ret; + nsep_epollInfo_t *epInfo; + struct epoll_event *events = + (struct epoll_event *) malloc(SK_MAX_EP_EVENT * + sizeof(struct epoll_event)); + struct epoll_event *innerEvt = + (struct epoll_event *) malloc(SK_MAX_EP_EVENT * + sizeof(struct epoll_event)); + struct list_node *fdEpiHead; + struct list_node *node; + struct epitem *epi = NULL; + struct eventpoll *ep = NULL; + + if (NULL == events || NULL == innerEvt) { - NSSOC_LOGERR ("malloc events failed"); + NSSOC_LOGERR("malloc events failed"); - if (events) + if (events) { - free (events); - events = NULL; /* Set NULL to pointer after free */ + free(events); + events = NULL; /* Set NULL to pointer after free */ } - if (innerEvt) + if (innerEvt) { - free (innerEvt); - innerEvt = NULL; /* Set NULL to pointer after free */ + free(innerEvt); + innerEvt = NULL; /* Set NULL to pointer after free */ } - /* When ks_ep_thread failed, it should set g_ksInfo.thread_inited ks_true, otherwise,it will result kernel_stack_register in dead loop */ - g_ksInfo.thread_inited = ks_true; - return NULL; + + /* When ks_ep_thread failed, it should set g_ksInfo.thread_inited ks_true, otherwise,it will result kernel_stack_register in dead loop */ + g_ksInfo.thread_inited = ks_true; + return NULL; } - if (-1 == g_ksInfo.epfd) + retval = + memset_s(events, SK_MAX_EP_EVENT * sizeof(struct epoll_event), 0, + SK_MAX_EP_EVENT * sizeof(struct epoll_event)); + retval |= + memset_s(innerEvt, SK_MAX_EP_EVENT * sizeof(struct epoll_event), 0, + SK_MAX_EP_EVENT * sizeof(struct epoll_event)); + + if (EOK != retval) { - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_create, (1), g_ksInfo.epfd); + free(events); + events = NULL; + free(innerEvt); + innerEvt = NULL; + g_ksInfo.thread_inited = ks_true; + return NULL; } - if (-1 == g_ksInfo.epfd) + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_create, (1), g_ksInfo.epfd); + + if (-1 == g_ksInfo.epfd) { - g_ksInfo.thread_inited = ks_true; + g_ksInfo.thread_inited = ks_true; - if (events) + if (events) { - free (events); - events = NULL; /* Set NULL to pointer after free */ + free(events); + events = NULL; /* Set NULL to pointer after free */ } - if (innerEvt) + if (innerEvt) { - free (innerEvt); - innerEvt = NULL; /* Set NULL to pointer after free */ + free(innerEvt); + innerEvt = NULL; /* Set NULL to pointer after free */ } - return NULL; + return NULL; } - g_ksInfo.thread_inited = ks_true; + g_ksInfo.thread_inited = ks_true; - do + do { - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_wait, - (g_ksInfo.epfd, events, SK_MAX_EP_EVENT, -1), eventNum); + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_wait, + (g_ksInfo.epfd, events, SK_MAX_EP_EVENT, -1), + eventNum); - if (0 == eventNum) + if (0 == eventNum) { - sys_sleep_ns (0, 100000); + sys_sleep_ns(0, 100000); } - for (loop = 0; loop < eventNum; loop++) + for (loop = 0; loop < eventNum; loop++) { - NSSOC_LOGDBG ("Epoll]events=%u,epfd=%d", events[loop].events, - events[loop].data.fd); + NSSOC_LOGDBG("Epoll]events=%u,epfd=%d", events[loop].events, + events[loop].data.fd); - if (events[loop].events & EPOLLIN) + if (events[loop].events & EPOLLIN) { - int i = 0, num = 0, ret = 0, epfd = events[loop].data.fd; - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_wait, - (epfd, innerEvt, SK_MAX_EP_EVENT, 0), num); + int i = 0, num = 0, epfd = events[loop].data.fd; + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_wait, + (epfd, innerEvt, SK_MAX_EP_EVENT, 0), num); - if (0 == num) + if (0 == num) { - NSSOC_LOGWAR ("Num is zero"); - continue; + /* remove it becasue print in normal scenario */ + NSSOC_LOGDBG("Num is zero]epfd=%d", epfd); + continue; } - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_ctl, - (g_ksInfo.epfd, EPOLL_CTL_DEL, epfd, NULL), - ret); + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_ctl, + (g_ksInfo.epfd, EPOLL_CTL_DEL, epfd, NULL), + ret); - ret = -1; - for (i = 0; i < num; i++) + for (i = 0; i < num; i++) { - ret &= - g_ksInfo.regVal.event_cb (innerEvt[i].data.ptr, - innerEvt[i].events); - NSSOC_LOGDBG ("Kernel got one event]i=%d,ptr=%d,events=%u", - i, innerEvt[i].data.ptr, innerEvt[i].events); - } + epInfo = nsep_get_info_by_sock(innerEvt[i].data.fd); + + if (epInfo + && (epInfo->rmidx < 0 + || epInfo->rmidx == g_ksInfo.regVal.type)) + { + dmm_spin_lock_with_pid((dmm_spinlock_t + *) (&epInfo->epiLock)); + fdEpiHead = + (struct list_node *) + SHMEM_ADDR_SHTOL(epInfo->epiList.head); + node = + (struct list_node *) + SHMEM_ADDR_SHTOL(fdEpiHead->next); + while (node) + { + + epi = + (struct epitem *) ep_list_entry(node, + struct + epitem, + fllink); + + node = + (struct list_node *) + SHMEM_ADDR_SHTOL(node->next); + ep = (struct eventpoll *) + SHMEM_ADDR_SHTOL(epi->ep); + + if (!(epi->event.events & innerEvt[i].events)) + { + continue; + } + + if (ep->pid != get_sys_pid()) + { + continue; + } + + epi->revents |= innerEvt[i].events; + } + + dmm_spin_unlock((dmm_spinlock_t + *) (&epInfo->epiLock)); + g_ksInfo.regVal.event_cb(epInfo, innerEvt[i].events, + EVENT_INFORM_APP); + NSSOC_LOGDBG + ("Kernel got one event]i=%d,fd=%d,events=%u", i, + innerEvt[i].data.fd, innerEvt[i].events); + } - if (ret) - { - struct epoll_event ev; - ev.data.fd = epfd; - ev.events = EPOLLIN; - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_ctl, - (g_ksInfo.epfd, EPOLL_CTL_ADD, epfd, &ev), - ret); } } } } - while (1); + while (1); +} +int kernel_load_default_rd(void *table) +{ + rd_ip_data ip_data; + ip_data.addr = inet_addr("127.0.0.1"); // loopback address + ip_data.masklen = 0; + ip_data.resev[0] = ip_data.resev[1] = 0; + (void) nstack_rd_ip_node_insert(RD_KERNEL_NAME, &ip_data, table); + NSSOC_LOGINF("successfully load default rd"); + return 0; } -int -kernel_fd_check (int fd, int flag) +void *kernel_get_ip_shmem() { - struct epoll_event event; - event.data.fd = fd; - event.events = EPOLLIN | EPOLLERR; - if (fd == g_ksInfo.checkEpollFD) - { - return 0; - } + return krd_table; +} - /*in order to reduce the cost of epoll ctl */ - if (STACK_FD_FUNCALL_CHECK == flag) - { - return 1; - } +int kernel_module_init() +{ + krd_table = nstack_local_rd_malloc(); - if (-1 == - nsfw_base_epoll_ctl (g_ksInfo.checkEpollFD, EPOLL_CTL_ADD, fd, &event)) + if (!krd_table) { - return 0; + NSSOC_LOGERR("kernel rd table create failed!"); + return -1; } - nsfw_base_epoll_ctl (g_ksInfo.checkEpollFD, EPOLL_CTL_DEL, fd, NULL); - return 1; -} - -int -kernel_prewait_proc (int epfd) -{ - int ret = 0; - struct epoll_event ep_event; - - NSSOC_LOGINF ("epfd=%d was added", epfd); - if (epfd < 0) + if (nstack_rd_parse(RD_KERNEL_NAME, krd_table)) { - return -1; + NSSOC_LOGWAR("kernel parse rd data failed, load default instead"); + nstack_rd_table_clear(krd_table); + return kernel_load_default_rd(krd_table); } - ep_event.data.fd = epfd; - ep_event.events = EPOLLIN | EPOLLET; - ret = lk_epollctl (0, EPOLL_CTL_ADD, epfd, &ep_event); - return ret; + + return 0; } -unsigned int -kernel_ep_fd_add (int epFD, int proFD, int ctl_ops, - struct epoll_event *events, void *pdata) +int kernel_stack_register + (nstack_socket_ops * ops, + nstack_event_ops * val, nstack_proc_ops * fddeal) { - struct epoll_event tmpEvt; - int ret = 0; - tmpEvt.data.ptr = pdata; - tmpEvt.events = events->events; - NSSOC_LOGINF ("epfd=%d,fd=%d,ops=%d, events=%u", epFD, proFD, ctl_ops, - events->events); - switch (ctl_ops) + /* Input parameter validation */ + if ((NULL == ops) || (NULL == val) || (NULL == fddeal)) { - case nstack_ep_triggle_add: - ret = nsfw_base_epoll_ctl (epFD, EPOLL_CTL_ADD, proFD, &tmpEvt); - break; - case nstack_ep_triggle_mod: - ret = nsfw_base_epoll_ctl (epFD, EPOLL_CTL_MOD, proFD, &tmpEvt); - break; - case nstack_ep_triggle_del: - ret = nsfw_base_epoll_ctl (epFD, EPOLL_CTL_DEL, proFD, &tmpEvt); - break; - default: - ret = -1; - break; + NSPOL_LOGERR("input param is NULL"); + return ks_fail; } - return ret; -} -int -kernel_socket (int a, int b, int c) -{ +#undef NSTACK_MK_DECL +#define NSTACK_MK_DECL(ret, fn, args) \ + g_ksInfo.libcOps.pf##fn = nsfw_base_##fn; +/*this file can be included more than once */ +#include "declare_syscalls.h.tmpl" - return nsfw_base_socket (a, b, c); -} + g_ksInfo.epfd = -1; + g_ksInfo.regVal = *val; -int -kernel_module_init () -{ - int retval = 0; +#ifdef KERNEL_FD_SUPPORT + g_ksInfo.thread_inited = ks_false; - g_ksInfo.thread_inited = ks_false; - retval = pthread_create (&g_ksInfo.ep_thread, NULL, ks_ep_thread, NULL); - if (retval != 0) - { - NSPOL_LOGERR ("kernel ep thread create fail, errno:%d!", errno); - return ks_fail; - } + NSSOC_LOGDBG("start to regist stack"); - /* The earlier thread "ep_thread" created will exit automatically when - return failure from below if any failure */ - retval = pthread_setname_np (g_ksInfo.ep_thread, K_EPOLL_THREAD_NAME); - if (retval != 0) + if (pthread_create(&g_ksInfo.ep_thread, NULL, ks_ep_thread, NULL)) { - NSMON_LOGERR - ("pthread_setname_np failed for ep_thread]retval=%d, errno:%d", - retval, errno); - /*set thread name failed no need to return */ + NSPOL_LOGERR("Err!"); + return ks_fail; } - NSSOC_LOGDBG ("New thread started"); + /* The earlier thread "ep_thread" created will exit automatically when + return failure from below if any failure */ + int retval = 0; - do + if (pthread_setname_np(g_ksInfo.ep_thread, K_EPOLL_THREAD_NAME)) { - sys_sleep_ns (0, 0); + NSMON_LOGERR("pthread_setname_np failed for ep_thread]retval=%d", + retval); + /*set thread name failed no need to return */ } - while (!g_ksInfo.thread_inited); - if (-1 == g_ksInfo.epfd) + NSSOC_LOGDBG("New thread started"); + + do { - NSPOL_LOGERR ("thread epoll create Err!"); - retval |= -1; + sys_sleep_ns(0, 0); } - return retval; -} - -int -kernel_fd_alloc () -{ - return nsfw_base_socket (AF_UNIX, SOCK_DGRAM, 0); -} + while (!g_ksInfo.thread_inited); -int -kernel_stack_register (nstack_proc_cb * ops, nstack_event_cb * val) -{ - int retval = 0; - /* Input parameter validation */ - if ((NULL == ops) || (NULL == val)) + if (-1 == g_ksInfo.epfd) { - NSPOL_LOGERR ("input param is NULL"); - return ks_fail; + NSPOL_LOGERR("Err!"); + retval = -1; } -#undef NSTACK_MK_DECL -#define NSTACK_MK_DECL(ret, fn, args) \ - g_ksInfo.libcOps.pf##fn = nsfw_base_##fn; - -#include "declare_syscalls.h" - - g_ksInfo.regVal = *val; +#endif - /*create a efpd to check fd is ok */ - if (g_ksInfo.checkEpollFD == -1) - { - g_ksInfo.checkEpollFD = nsfw_base_epoll_create (1); - } + *ops = g_ksInfo.libcOps; - NSSOC_LOGDBG ("start to regist stack"); + NSTACK_SET_OPS_FUN(ops, listen, lk_listen); + NSTACK_SET_OPS_FUN(ops, epoll_ctl, lk_epollctl); - ops->socket_ops = g_ksInfo.libcOps; - MEMSET_S (&(ops->extern_ops), sizeof (ops->extern_ops), 0, - sizeof (ops->extern_ops)); - NSTACK_SET_OPS_FUN (&(ops->socket_ops), listen, lk_listen); - NSTACK_SET_OPS_FUN (&(ops->socket_ops), epoll_ctl, lk_epollctl); - NSTACK_SET_OPS_FUN (&(ops->socket_ops), socket, kernel_socket); - ops->extern_ops.stack_fd_check = kernel_fd_check; - ops->extern_ops.ep_ctl = kernel_ep_fd_add; - ops->extern_ops.ep_prewait_proc = kernel_prewait_proc; - ops->extern_ops.module_init = kernel_module_init; - ops->extern_ops.module_init_child = kernel_module_init; - ops->extern_ops.stack_alloc_fd = kernel_fd_alloc; + /* don't close file descriptor */ - /* don't close file descriptor */ + fddeal->module_init = kernel_module_init; + fddeal->get_ip_shmem = kernel_get_ip_shmem; - return retval ? ks_fail : ks_success; +#ifdef KERNEL_FD_SUPPORT + return retval ? ks_fail : ks_success; +#else + return ks_success; +#endif } diff --git a/src/nSocket/kernel/linux_kernel_module.h b/src/nSocket/kernel/linux_kernel_module.h index 01e0330..cdb88f0 100644 --- a/src/nSocket/kernel/linux_kernel_module.h +++ b/src/nSocket/kernel/linux_kernel_module.h @@ -17,10 +17,11 @@ #ifndef _LINUX_KERNEL_MODULE_H_ #define _LINUX_KERNEL_MODULE_H_ -#include "nstack_dmm_api.h" +#include "nstack_callback_ops.h" -#define K_SELECT_THREAD_NAME "kernel_select" -#define K_EPOLL_THREAD_NAME "kernel_epoll" +#define DMM_MEM_LIB_PATH_LEN 256 + +#define K_EPOLL_THREAD_NAME "nstk_ker_epoll" #ifndef ks_success #define ks_success 0 @@ -42,20 +43,21 @@ typedef char ks_bool; #define ks_true 1 #endif -int kernel_stack_register (nstack_proc_cb * ops, nstack_event_cb * val); +int kernel_stack_register + (nstack_socket_ops * ops, + nstack_event_ops * val, nstack_proc_ops * fddeal); typedef struct { - nstack_event_cb regVal; - int epfd; - int checkEpollFD; - pthread_t ep_thread; - ks_bool thread_inited; - pthread_t select_thread; //listen select events - nstack_socket_ops libcOps; + nstack_event_ops regVal; + int epfd; + pthread_t ep_thread; + ks_bool thread_inited; + pthread_t select_thread; //listen select events + nstack_socket_ops libcOps; } kernel_stack_info_t; extern kernel_stack_info_t g_ksInfo; -extern int linux_kernel_stack_init (void); +extern int linux_kernel_stack_init(void); #endif diff --git a/src/nSocket/kernel/linux_kernel_socket.c b/src/nSocket/kernel/linux_kernel_socket.c index b7ac028..5b7c9fd 100644 --- a/src/nSocket/kernel/linux_kernel_socket.c +++ b/src/nSocket/kernel/linux_kernel_socket.c @@ -29,36 +29,36 @@ #include "nstack_sockops.h" #include "nstack_securec.h" -int -lk_listen (int sockfd, int backlog) +int lk_listen(int sockfd, int backlog) { - int ret = -1; + int ret = -1; - NSTACK_CAL_FUN (&g_ksInfo.libcOps, listen, (sockfd, backlog), ret); - return ret; + NSTACK_CAL_FUN(&g_ksInfo.libcOps, listen, (sockfd, backlog), ret); + + return ret; } -int -lk_epollctl (int epfd, int op, int protoFd, struct epoll_event *event) +int lk_epollctl(int epfd, int op, int protoFd, struct epoll_event *event) { - int retVal; - struct epoll_event ev; + int retVal; + struct epoll_event ev; - /* Input parameter validation */ - if (NULL == event) + /* Input parameter validation */ + if (NULL == event) { - NSSOC_LOGERR ("input param event is NULL"); - return -1; + NSSOC_LOGERR("input param event is NULL"); + return -1; } - retVal = - MEMCPY_S (&ev, sizeof (struct epoll_event), event, - sizeof (struct epoll_event)); - if (EOK != retVal) + /*There are some unsafe function ,need to be replace with safe function */ + retVal = + memcpy_s(&ev, sizeof(struct epoll_event), event, + sizeof(struct epoll_event)); + if (EOK != retVal) { - NSSOC_LOGERR ("MEMCPY_S failed]ret=%d", retVal); - return -1; + NSSOC_LOGERR("memcpy_s failed]ret=%d", retVal); + return -1; } - ev.data.fd = protoFd; - return g_ksInfo.libcOps.pfepoll_ctl (g_ksInfo.epfd, op, protoFd, &ev); + ev.data.fd = protoFd; + return g_ksInfo.libcOps.pfepoll_ctl(g_ksInfo.epfd, op, protoFd, &ev); } diff --git a/src/nSocket/kernel/linux_kernel_socket.h b/src/nSocket/kernel/linux_kernel_socket.h index 9c3d692..790ab2c 100644 --- a/src/nSocket/kernel/linux_kernel_socket.h +++ b/src/nSocket/kernel/linux_kernel_socket.h @@ -23,9 +23,9 @@ extern "C"{ /* *INDENT-ON* */ #endif -extern int lk_listen (int sockfd, int backlog); -extern int lk_epollctl (int epfd, int op, int protoFd, - struct epoll_event *event); +extern int lk_listen(int sockfd, int backlog); +extern int lk_epollctl(int epfd, int op, int protoFd, + struct epoll_event *event); #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/nSocket/nstack/event/epoll/nstack_epoll.c b/src/nSocket/nstack/event/epoll/nstack_epoll.c new file mode 100644 index 0000000..d1a006f --- /dev/null +++ b/src/nSocket/nstack/event/epoll/nstack_epoll.c @@ -0,0 +1,887 @@ +/* +* +* 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_eventpoll.h" +#include "nstack_log.h" +#include "nsfw_recycle_api.h" +#include "nstack_securec.h" +#include "nstack_module.h" +#include "nstack_sockops.h" +#include "nsfw_mem_api.h" +#include "nstack_fd_mng.h" +#include "nstack.h" +#include "dmm_spinlock.h" +#include "nsfw_base_linux_api.h" +#include "nstack_dmm_dfx.h" +#include "nstack_epoll_api.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +const int EPOLL_DFX_OPS_MAP[nstack_ep_event_max] = + { DMM_APP_EPOLL_ADD_TICK, DMM_APP_EPOLL_MOD_TICK, DMM_APP_EPOLL_DEL_TICK, + DMM_DFX_MAX +}; + +static inline void *nstack_ep_triggle + (int proFD, + int modInx, + int triggle_ops, struct epitem *epi, nsep_epollInfo_t * epinfo) +{ + void *data = NULL; + int events = 0; + + if (nstack_fd_deal[modInx].ep_triggle != NULL) + { + data = + nstack_fd_deal[modInx].ep_triggle(proFD, triggle_ops, epinfo, + &events); + if (data && epi) + { + struct stat_epfd_info tmp_epfd_info; + struct eventpoll *ep = + (struct eventpoll *) SHMEM_ADDR_SHTOL(epi->ep); + switch (triggle_ops) + { + case nstack_ep_triggle_add: + if (epi->event.events & events) + { + NSTACK_EPOLL_EVENT_ADD(epinfo, events, + EVENT_INFORM_APP); + } + break; + case nstack_ep_triggle_mod: + if (epi->event.events & events) + { + NSTACK_EPOLL_EVENT_ADD(epinfo, events, + EVENT_INFORM_APP); + } + else + { + NSTACK_EPOLL_EVENT_DEL(epi, EPOLLET); + } + break; + default: + break; + } + tmp_epfd_info.epoll_wait_tick = ep->epoll_wait_tick; + tmp_epfd_info.epfd = ep->epfd; + tmp_epfd_info.epoll_fork_flag = ep->epoll_fork_flag; + tmp_epfd_info.hhpid = get_sys_pid(); + nsep_epollInfo_t *epfd_info = nsep_get_info_by_sock(ep->epfd); + if (NULL != epfd_info) + tmp_epfd_info.ep_sleepTime = epfd_info->sleepTime; + else + tmp_epfd_info.ep_sleepTime = 0; + nstack_dfx_state_update((u64) proFD, modInx, + EPOLL_DFX_OPS_MAP[triggle_ops], + &tmp_epfd_info); + } + } + return data; +} + +#define nstack_ep_get_evt(_epInfo, _epi) do\ +{\ + if ((_epInfo)->rmidx != -1 && nstack_fd_deal[(_epInfo)->rmidx].ep_getEvt != NULL)\ + {\ + int evt_events;\ + evt_events= nstack_fd_deal[(_epInfo)->rmidx].ep_getEvt((_epInfo)->rlfd);\ + if(((_epi)->event.events & EPOLLIN) && (evt_events & EPOLLIN))\ + (_epi)->revents |=EPOLLIN;\ + if(((_epi)->event.events & EPOLLOUT) && (evt_events & EPOLLOUT))\ + (_epi)->revents |=EPOLLOUT; \ + }\ +}while(0)\ + +#define NSEP_IS_SOCK_VALID(_sock) ((_sock) >= 0 && (u32_t)(_sock) < NSTACK_KERNEL_FD_MAX) + +/* + * Triggle epoll events of stack + * ep - eventpoll instance + * fdInf - file descriptor of stack + * triggle_ops - why triggle + */ +/*no need null pointer check*/ +void nsep_epctl_triggle(struct epitem *epi, nsep_epollInfo_t * info, + int triggle_ops) +{ + int modInx; + int protoFd = -1; + void *data = NULL; + + NSSOC_LOGDBG("info=%p,info->rmidx=%d,triggle_ops=%d", info, info->rmidx, + triggle_ops); + + /* Now need to triggle userspace network stack events after add operation */ + if (info->rmidx >= 0) + { + if (info->rmidx != nstack_get_linux_mid()) + { + /* fix overflow type */ + if ((info->rmidx >= NSEP_SMOD_MAX) + || (info->rmidx >= NSTACK_MAX_MODULE_NUM)) + { + return; + } + data = + nstack_ep_triggle(info->rlfd, info->rmidx, triggle_ops, epi, + info); + if ((NULL != data) && (nstack_ep_triggle_add == triggle_ops)) + { + info->private_data = (void *) SHMEM_ADDR_LTOSH(data); + info->epaddflag[info->rmidx] = 1; + } + NSSOC_LOGDBG + ("info=%p,module=%s,protoFd=%d,triggle_ops=%d, ret:%p", info, + nstack_get_module_name_by_idx(info->rmidx), info->rlfd, + triggle_ops, data); + } + } + else + { + nstack_each_mod_inx(modInx) + { + if ((modInx >= NSEP_SMOD_MAX) + || (modInx >= NSTACK_MAX_MODULE_NUM)) + { + return; + } + protoFd = info->protoFD[modInx]; + if (modInx == nstack_get_linux_mid() || -1 == protoFd) + continue; // Don't do anything , epoll_wait will do for you + + data = nstack_ep_triggle(protoFd, modInx, triggle_ops, epi, info); + if ((NULL != data) && (nstack_ep_triggle_add == triggle_ops)) + { + info->private_data = (void *) SHMEM_ADDR_LTOSH(data); + info->epaddflag[modInx] = 1; + } + NSSOC_LOGDBG + ("info=%p,module=%s,protoFd=%d,triggle_ops=%d, ret:%p", info, + nstack_get_module_name_by_idx(modInx), protoFd, triggle_ops, + data); + } + } +} + +NSTACK_STATIC + void nsep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) +{ + + struct ep_rb_node **p = &ep->rbr.rb_node, *parent = NULL; /*not null here */ + struct epitem *epic; + u32_t loopCnt = 0; + + while (*p) + { + ++loopCnt; + if (loopCnt > NSTACK_MAX_EPITEM_NUM) + { + NSSOC_LOGERR("Loop out of range!!!!"); + break; + } + + parent = (struct ep_rb_node *) SHMEM_ADDR_SHTOL(*p); + + epic = ep_rb_entry(parent, struct epitem, rbn); + + if (epi->fd > epic->fd) + { + p = &(parent->rb_right); + } + else + { + p = &(parent->rb_left); + } + } + + ep_rb_link_node(&epi->rbn, parent, p); + ep_rb_insert_color(&epi->rbn, &ep->rbr); /*not null here */ + +} + +void _InOrder(struct ep_rb_node *root) +{ + struct epitem *epi = NULL; + nsep_epollInfo_t *epInfo = NULL; + stat_epitem_info_t epitem_info; + + if (NULL == root) + { + return; + } + + _InOrder((struct ep_rb_node *) SHMEM_ADDR_SHTOL(root->rb_left)); + + epi = ep_rb_entry(root, struct epitem, rbn); + + epInfo = (nsep_epollInfo_t *) SHMEM_ADDR_SHTOL(epi->private_data); + if (NULL != epInfo) + { + epitem_info.event = epi->event; + epitem_info.is_linked = EP_HLIST_NODE_LINKED(&epi->rdllink); + nstack_dfx_state_update((u64) epInfo->rlfd, epInfo->rmidx, + DMM_APP_EPOLL_WAIT_FAIL, &epitem_info); + } + _InOrder((struct ep_rb_node *) SHMEM_ADDR_SHTOL(root->rb_right)); + +} + +void nsep_notify_fd_epoll_wait_fail(struct eventpoll *ep) +{ + + if (!ep) + return; + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->sem)); /*do not need return value */ + _InOrder((struct ep_rb_node *) SHMEM_ADDR_SHTOL(ep->rbr.rb_node)); + dmm_spin_unlock((dmm_spinlock_t *) (&ep->sem)); +} + +/* + * This function is called by epctl_add , it will create one epitem of fd, and insert to eventpoll + */ +NSTACK_STATIC + int nsep_insert_node(struct eventpoll *ep, + nsep_epollInfo_t * epfd_epInfo, + struct epoll_event *event, nsep_epollInfo_t * epInfo) +{ + struct epitem *epi; + + if (nsep_alloc_epitem(&epi)) + { + NSSOC_LOGERR("Can't alloc epitem"); + errno = ENOMEM; + return -1; + } + + EP_HLIST_INIT_NODE(&epi->rdllink); + + epi->ptr_reserve = NULL; + epi->ep_spl = (struct spl_conn_pool *) (epfd_epInfo->ep_conn); + epi->ep = (struct eventpoll *) SHMEM_ADDR_LTOSH_EXT(ep); + epi->epInfo = (nsep_epollInfo_t *) SHMEM_ADDR_LTOSH_EXT(epInfo); + epi->revents = 0; + epi->event = *event; /*no need null pointer check */ + + EP_LIST_INIT_NODE(&epi->fllink); + EP_HLIST_INIT_NODE(&epi->txlink); + epi->fd = epInfo->fd; /*no need null pointer check */ + + /* Add the current item to the list of active epoll hook for this file + This should lock because file descriptor may be called by other eventpoll */ + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&epInfo->epiLock)); /*do not need return value */ + ep_list_add_tail(&epInfo->epiList, &epi->fllink); + epi->private_data = (void *) SHMEM_ADDR_LTOSH_EXT(epInfo); + dmm_spin_unlock((dmm_spinlock_t *) (&epInfo->epiLock)); + + /* Add epitem to eventpoll fd list, don't need lock here because epoll_ctl will lock before calling this function */ + nsep_rbtree_insert(ep, epi); + + /* Need to poll the events already stored in stack */ + nsep_epctl_triggle(epi, epInfo, nstack_ep_triggle_add); + + NSSOC_LOGINF("epfd=%d,ep=%p,fd=%d,epi=%p", ep->epfd, ep, epInfo->fd, epi); + + return 0; +} + +#ifdef KERNEL_FD_SUPPORT +NSTACK_STATIC int nsep_is_add_valid(int fd, struct epoll_event *events) +{ + if (-1 == nsep_get_manager()->checkEpollFD) + { + return -1; + } + if (-1 == + nsfw_base_epoll_ctl(nsep_get_manager()->checkEpollFD, EPOLL_CTL_ADD, + fd, events)) + { + return -1; + } + + nsfw_base_epoll_ctl(nsep_get_manager()->checkEpollFD, EPOLL_CTL_DEL, fd, NULL); /*do not need return value */ + return 0; +} + +NSTACK_STATIC + int nsep_add_to_kernel(int epfd, int fd, const struct epoll_event *events) +{ + struct epoll_event tmpEvt; + tmpEvt.data.fd = fd; + tmpEvt.events = events->events; /*no need null pointer check */ + NSSOC_LOGINF("epfd=%d,fd=%d,events=%u", epfd, fd, events->events); + return nsfw_base_epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &tmpEvt); +} + +NSTACK_STATIC + int nsep_mod_to_kernel(int epfd, int fd, const struct epoll_event *events) +{ + struct epoll_event tmpEvt; + tmpEvt.data.fd = fd; + tmpEvt.events = events->events; /*no need null pointer check */ + NSSOC_LOGINF("epfd=%d,fd=%d,events=%u", epfd, fd, events->events); + return nsfw_base_epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &tmpEvt); +} +#endif + +int nsep_epctl_add(struct eventpoll *ep, nsep_epollInfo_t * epfd_epInfo, + int fd, struct epoll_event *events) +{ + + int ret = 0; + + NSSOC_LOGINF("epfd=%d,fd=%d,events=%u", ep->epfd, fd, events->events); + + nsep_epollInfo_t *epInfo = nsep_get_info_by_sock(fd); + + if (NULL == epInfo) + { +#ifdef KERNEL_FD_SUPPORT + if (-1 == nsep_is_add_valid(fd, events)) + { + NSSOC_LOGERR("Invalid add check nfd=%d]", fd); + return -1; + } + if (-1 == nsep_alloc_info_with_sock(fd)) + { + NSSOC_LOGERR("Can't alloc epInfo for nfd]nfd=%d", fd); + return -1; + } + nsep_set_info_proto_fd(fd, nstack_get_linux_mid(), fd); + epInfo = nsep_get_info_by_sock(fd); +#else + /*if FD is not in use, epoll_ctl_add return fail */ + NSSOC_LOGERR("Invalid add check nfd]nfd=%d", fd); + return -1; +#endif + } + + if (NULL == epfd_epInfo) + { + NSSOC_LOGWAR("epfd_epInfo is NULL]epfd=%d,fd=%d ", ep->epfd, + epInfo->fd); + return -1; + } + + ret = nsep_insert_node(ep, epfd_epInfo, events, epInfo); + if (0 != ret) + { + NSSOC_LOGWAR("insert fail]epfd=%d,fd=%d ", ep->epfd, epInfo->fd); + return -1; + } + +#ifdef KERNEL_FD_SUPPORT + /* Add fd to epoll fd to support kernel epoll thread */ + if (-1 == epInfo->rmidx || epInfo->rmidx == nstack_get_linux_mid()) + { + if (-1 == nsep_add_to_kernel(ep->epfd, epInfo->fd, events)) + { /*no need null pointer check */ + NSSOC_LOGWAR("epctl fail]epfd=%d,fd=%d,errno=%d", ep->epfd, + epInfo->fd, errno); + return -1; + } + } +#endif + + return 0; +} + +int nsep_epctl_del(struct eventpoll *ep, struct epitem *epi) +{ + int ret = 0; + + nsep_epollInfo_t *epInfo = (nsep_epollInfo_t *) SHMEM_ADDR_SHTOL(epi->private_data); /*no need null pointer check */ + NSSOC_LOGINF("epfd=%d,fd=%d,epi=%p", ep->epfd, epi->fd, epi); + +#ifdef KERNEL_FD_SUPPORT + nsfw_base_epoll_ctl(ep->epfd, EPOLL_CTL_DEL, epi->fd, NULL); /*do not need return value */ +#endif + nsep_epctl_triggle(epi, epInfo, nstack_ep_triggle_del); + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&epInfo->epiLock)); /*do not need return value */ + /* Here need to check because nstack_close may has removed this epi->fllink */ + ep_list_del(&epInfo->epiList, &epi->fllink); /*no need null pointer check */ + /* after close fd in epfd, epfd still can epoll_wait EPOLLIN event for these fd */ + (void) nstack_epoll_event_dequeue(epi, 0); + dmm_spin_unlock((dmm_spinlock_t *) (&epInfo->epiLock)); + nsep_epctl_triggle(NULL, epInfo, nstack_ep_triggle_inform_app); + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->lock)); /*do not need return value */ + ret = nstack_ep_unlink(ep, epi); + dmm_spin_unlock((dmm_spinlock_t *) (&ep->lock)); /*no need null pointer check */ + nsep_free_epitem(epi); /*do not need return value */ + + return ret; +} + +/*no need null pointer check*/ +int nsep_epctl_mod(struct eventpoll *ep, + nsep_epollInfo_t * epInfo, + struct epitem *epi, struct epoll_event *events) +{ + if (NULL == epInfo) + { + errno = EINVAL; + NSSOC_LOGWAR("epfd=%d, intput epInfo is null err", ep->epfd); + return -1; + } + + NSSOC_LOGINF("epfd=%d,fd=%d,events=%u", ep->epfd, epInfo->fd, + events->events); + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->lock)); /*do not need return value */ + epi->event = *events; /* kernel tells me that I need to modify epi->event in lock context */ + dmm_spin_unlock((dmm_spinlock_t *) (&ep->lock)); + +#ifdef KERNEL_FD_SUPPORT + /* Modify fd to epoll fd to support kernel epoll thread */ + if (-1 == epInfo->rmidx || epInfo->rmidx == nstack_get_linux_mid()) + { + if (-1 == nsep_mod_to_kernel(ep->epfd, epInfo->fd, events)) + { + NSSOC_LOGWAR("epctl fail]epfd=%d,fd=%d,errno=%d", ep->epfd, + epInfo->fd, errno); + return -1; + } + } +#endif + + nsep_epctl_triggle(epi, epInfo, nstack_ep_triggle_mod); + return 0; +} + +/* + * Called by epoll_wait + * Wait until events come or timeout + */ + /*no need to check return value */ +int nsep_ep_poll(struct eventpoll *ep, struct epoll_event *events, + int maxevents, struct spl_conn_pool *ep_conn) +{ + int evt = 0; + struct ep_hlist_node *node = NULL; + struct epitem *epi = NULL; + i32 enQueRet = 0; + void *ring_hd = NULL; + unsigned int tmp_revents = 0; + + if (maxevents <= 0 || !events) + return 0; + + if (NULL == ep_conn) + { + goto rdlist_check; + } + + ring_hd = SHMEM_ADDR_SHTOL(ep_conn->ring_hd); + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->sem)); + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->lock)); + while (1) + { + enQueRet = nsfw_mem_ring_dequeue(ring_hd, (void **) &epi); + if (1 != enQueRet) + { + break; + } + /* dont clear epi successfully, it cause app coredump */ + nsep_epollInfo_t *epInfo = + (nsep_epollInfo_t *) SHMEM_ADDR_SHTOL(epi->private_data); + if ((NULL == epInfo) || (NULL == epi->ep)) + { + NSPOL_LOGERR + ("epInfo or ep is NULL]ep_conn=%p,ep=%p,ring_hd=%p,epi=%p,epi->ep=%p,epInfo=%p", + ep_conn, ep, ring_hd, epi, SHMEM_ADDR_SHTOL(epi->ep), + epInfo); + continue; + } + epi->app_poll_count = epi->spl_enter_count; + /* dont clear epi successfully, it cause app coredump */ + if (ep != SHMEM_ADDR_SHTOL(epi->ep)) + { + NSPOL_LOGERR + ("ep_conn use by multi ep]ep_conn=%p,ep=%p,ring_hd=%p,epi=%p,epInfo=%p,epInfo->fd=%d,epi->ep=%p", + ep_conn, ep, ring_hd, epi, epInfo, epInfo->fd, + SHMEM_ADDR_SHTOL(epi->ep)); + continue; + } + + nstack_dfx_state_update((u64) epInfo->rlfd, epInfo->rmidx, + DMM_APP_EPOLL_WAIT_GET_TICK, NULL); + + if (!EP_HLIST_NODE_LINKED(&epi->rdllink)) + { + ep_hlist_add_tail(&ep->rdlist, &epi->rdllink); + } + + }; + + dmm_spin_unlock((dmm_spinlock_t *) (&ep->lock)); + dmm_spin_unlock((dmm_spinlock_t *) (&ep->sem)); + + rdlist_check: + + if (EP_HLIST_EMPTY(&ep->rdlist)) + { + NSSOC_LOGDBG("ep->rdlist is Empty, epfd=%d", ep->epfd); + return 0; + } + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->sem)); /*do not need return value */ + if (EP_HLIST_EMPTY(&ep->rdlist)) + goto out; + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->lock)); /*do not need return value */ + + struct ep_hlist_node *epRdHead = + (struct ep_hlist_node *) SHMEM_ADDR_SHTOL(ep->rdlist.head); + if (!epRdHead) + { + return 0; + } + node = (struct ep_hlist_node *) SHMEM_ADDR_SHTOL(epRdHead->next); + + while (node) + { + + epi = ep_hlist_entry(node, struct epitem, rdllink); + + node = (struct ep_hlist_node *) SHMEM_ADDR_SHTOL(node->next); + nsep_epollInfo_t *epInfo = + (nsep_epollInfo_t *) SHMEM_ADDR_SHTOL(epi->private_data); + epInfo = (nsep_epollInfo_t *) SHMEM_ADDR_SHTOL(epi->private_data); + + nstack_ep_get_evt(epInfo, epi); + + tmp_revents = epi->revents; + + /* app epoll_wait return 24 event, when the fd is in establish state */ + + while (!__sync_bool_compare_and_swap(&epi->revents, tmp_revents, 0)) + { /* daemon-stack don't have lock for err hup rdhup event, so here must ensure that daemon-stack don't modify it */ + tmp_revents = epi->revents; + }; + + if (tmp_revents) + { + events[evt].events = tmp_revents; + events[evt].data = epi->event.data; + NSSOC_LOGDBG("Add event]epfd=%d,fd=%d,events=%u", ep->epfd, + epi->fd, events[evt].events); + evt++; + nstack_dfx_state_update((u64) epInfo->rlfd, epInfo->rmidx, + DMM_APP_EPOLL_WAIT_EVENT, + (void *) (u64) tmp_revents); + } + + if (0 == tmp_revents || epi->event.events & EPOLLET) + { + NSSOC_LOGDBG("Del epi->rdllink,epfd=%d,fd=%d", ep->epfd, epi->fd); + ep_hlist_del(&ep->rdlist, &epi->rdllink); + } + + if (tmp_revents & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) + { + NSSOC_LOGINF("epfd=%d,fd=%d,epi=%p,revent=%u", ep->epfd, epi->fd, + epi, tmp_revents); + } + + if (evt >= maxevents) + break; + } + dmm_spin_unlock((dmm_spinlock_t *) (&ep->lock)); + out: + dmm_spin_unlock((dmm_spinlock_t *) (&ep->sem)); + + NSSOC_LOGDBG("Return epfd=%d,fd=%d,EP_HLIST_EMPTY(&ep->rdlist)=%d", + ep->epfd, epi ? epi->fd : -1, EP_HLIST_EMPTY(&ep->rdlist)); + + return evt; +} + +/*no need to check return value*/ + +void nsep_remove_epfd(nsep_epollInfo_t * pinfo) +{ + pid_t pid = get_sys_pid(); + struct list_node *prenode = NULL; + struct list_node *nextnode = NULL; + struct list_node **node_arry = NULL; + int lenth = NSTACK_MAX_EPOLL_INFO_NUM * sizeof(struct list_node *); + struct epitem *epi = NULL; + struct epitem *tepi = NULL; + struct eventpoll *ep = NULL; + u32_t i = 0; + u32_t icnt = 0; + + if (!pinfo) + { + return; + } + /*malloc a block memory to store epitem node, do not use list for maybe free item */ + /*malloc() & free() can be used */ + node_arry = (struct list_node **) malloc(lenth); + if (!node_arry) + { + NSSOC_LOGERR("remove fd from ep malloc mem fail]fd=%d,ep=%p", + pinfo->fd, pinfo->ep); + return; + } + /*add return value check */ + int retVal = memset_s(node_arry, lenth, 0, lenth); + if (EOK != retVal) + { + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + free(node_arry); /*free() can be used */ + return; + } + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&pinfo->epiLock)); /*do not need return value */ + /*list head must be not null */ + prenode = (struct list_node *) SHMEM_ADDR_SHTOL(pinfo->epiList.head); + nextnode = (struct list_node *) SHMEM_ADDR_SHTOL(prenode->next); + icnt = 0; + + /*find all node that pid is belong to itself */ + while (nextnode) + { + if (++i > NSTACK_MAX_EPOLL_INFO_NUM) + { + /*record the exception log */ + NSSOC_LOGERR("error maybe happen]free pinfo=%p", pinfo); + break; + } + + epi = ep_list_entry(nextnode, struct epitem, fllink); + if (pid == epi->pid) + { + prenode->next = nextnode->next; + nextnode->next = NULL; + /*put into release list */ + node_arry[icnt] = nextnode; + icnt++; + /* only can clear ring for epi that del */ + (void) nstack_epoll_event_dequeue(epi, 0); + } + else + { + prenode = nextnode; + } + nextnode = (struct list_node *) SHMEM_ADDR_SHTOL(prenode->next); + } + + dmm_spin_unlock((dmm_spinlock_t *) (&pinfo->epiLock)); + + /*free all epitem */ + for (i = 0; i < icnt; i++) + { + + epi = ep_list_entry(node_arry[i], struct epitem, fllink); + ep = (struct eventpoll *) SHMEM_ADDR_SHTOL(epi->ep); + if (ep) + { + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->sem)); + /* Here don't use epi you find before, use fd and ep to find the epi again.that is multithread safe */ + tepi = nsep_find_ep(ep, pinfo->fd); + /*record the exception log */ + if (epi != tepi) + { + NSSOC_LOGERR("remove fd:%d epi:%p tepi:%p erro maybe happen", + pinfo->fd, epi, tepi); + } + /*if tepi is null, epi maybe free by nsep_close_epfd, so no need to free again */ + if (tepi) + { +#ifdef KERNEL_FD_SUPPORT + nsfw_base_epoll_ctl(ep->epfd, EPOLL_CTL_DEL, tepi->fd, NULL); /*do not need return value */ +#endif + nsep_epctl_triggle(tepi, pinfo, nstack_ep_triggle_del); + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->lock)); /*do not need return value */ + (void) nstack_ep_unlink(ep, tepi); + dmm_spin_unlock((dmm_spinlock_t *) (&ep->lock)); + + nsep_free_epitem(epi); + } + dmm_spin_unlock((dmm_spinlock_t *) (&ep->sem)); + } + } + + nsep_epctl_triggle(NULL, pinfo, nstack_ep_triggle_inform_app); + /*malloc() & free() can be used */ + free(node_arry); + return; +} + +void nsep_close_epfd(struct eventpoll *ep) +{ + + if (!ep) + return; + + struct epitem *epi = NULL; + struct ep_rb_node *node = NULL; + + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->sem)); /*do not need return value */ + while ((node = ep_rb_first(&ep->rbr))) + { + + epi = ep_rb_entry(node, struct epitem, rbn); + + int ret = nsep_epctl_del(ep, epi); + + /* Avoid dead loop */ + if (ret) + { + NSSOC_LOGERR + ("nstack epctl del fail, will break to avoid dead loop]ep->fd=%d,epi->fd=%d", + ep->epfd, epi->fd); + break; + } + } + dmm_spin_unlock((dmm_spinlock_t *) (&ep->sem)); + nsep_free_eventpoll(ep); /*do not need return value */ +} + +/*no need to check null pointer*/ +static inline int nsp_epoll_close_kernel_fd(int sock, + nsep_epollInfo_t * epInfo) +{ + NSSOC_LOGINF("fd=%d,type=%d", sock, epInfo->fdtype); + int ret = 0; + nsep_remove_epfd(epInfo); + + u32_t pid = get_sys_pid(); + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&epInfo->freeLock)); /*do not need return value */ + int left_count = nsep_del_last_pid(&epInfo->pidinfo, pid); + dmm_spin_unlock((dmm_spinlock_t *) (&epInfo->freeLock)); + if (-1 == left_count) + { + NSSOC_LOGERR("pid not exist]fd=%d,type=%d,pid=%u", sock, + epInfo->fdtype, pid); + } + + if (0 == left_count) + { + ret = nsep_free_epinfo(epInfo); + NSSOC_LOGINF("epinfo removed]fd=%d,type=%d", sock, epInfo->fdtype); + } + + return ret; +} + +/*no need to check null pointer*/ +static inline int nsp_epoll_close_spl_fd(int sock, nsep_epollInfo_t * epInfo) +{ + NSSOC_LOGINF("fd=%d,type=%d", sock, epInfo->fdtype); + nsep_remove_epfd(epInfo); /*no need to check null pointer */ + return 0; +} + +/*no need to check null pointer*/ +static inline int nsp_epoll_close_ep_fd(int sock, nsep_epollInfo_t * epInfo) +{ + struct eventpoll *ep = SHMEM_ADDR_SHTOL(epInfo->ep); + struct spl_conn_pool *ep_conn = SHMEM_ADDR_SHTOL(epInfo->ep_conn); + u32_t pid = get_sys_pid(); + NSSOC_LOGINF("fd:%d is epoll fd ep:%p]", sock, ep); + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&epInfo->freeLock)); + int left_count = nsep_del_last_pid(&epInfo->pidinfo, pid); + dmm_spin_unlock((dmm_spinlock_t *) (&epInfo->freeLock)); + if (0 == left_count) + { + epInfo->ep = NULL; + epInfo->ep_conn = NULL; + nsep_close_epfd(ep); + /* must close ep fistly before free ep_conn, becasue if close ep_conn firstly, then this ep_conn will alloc by other epfd, + this time, now daemon-stack possiblely will report event using this ep_conn */ + (void) nsep_free_ep_spl_conn_ring(ep_conn); + nsep_free_epinfo(epInfo); + } + return 0; +} + +/*no need to check null pointer*/ +int nsep_epoll_close(int sock) +{ + int ret = 0; + nsep_epollInfo_t *epInfo = nsep_get_info_by_sock(sock); + if (!epInfo) + { + NSSOC_LOGDBG("epollsock close sock:%d is not exist", sock); + return 0; + } + + nsep_set_info_sock_map(sock, NULL); + + if (NSTACK_EPOL_FD == epInfo->fdtype) + { + return nsp_epoll_close_ep_fd(sock, epInfo); + } + + if (epInfo->rmidx == nstack_get_linux_mid()) + { + ret = nsp_epoll_close_kernel_fd(sock, epInfo); + } + else + { + ret = nsp_epoll_close_spl_fd(sock, epInfo); + } + + return ret; +} + +/* epinfo add pid */ +void nsep_fork(u32_t ppid) +{ + u32 cpid = get_sys_pid(); + nsep_epollManager_t *manager = nsep_get_manager(); + if (NULL == manager->infoSockMap) + { + NSSOC_LOGERR("infoSockMap is NULL]ppid=%u,cpid=%u", ppid, cpid); + return; + } + + nsep_epollInfo_t *epinfo = NULL; + int pos; + for (pos = 0; (u32_t) pos < NSTACK_KERNEL_FD_MAX; pos++) + { + epinfo = manager->infoSockMap[pos]; + if (epinfo) + { + if (nsep_add_pid(&epinfo->pidinfo, cpid) != 0) + { + NSSOC_LOGERR("epinfo add pid failed]fd=%d,ppid=%u.cpid=%u", + pos, ppid, cpid); + } + else + { + NSSOC_LOGDBG("epinfo add pid ok]fd=%d,ppid=%u.cpid=%u", pos, + ppid, cpid); + } + } + } +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/nSocket/nstack/event/epoll/nstack_eventpoll.c b/src/nSocket/nstack/event/epoll/nstack_eventpoll.c deleted file mode 100644 index a8b3757..0000000 --- a/src/nSocket/nstack/event/epoll/nstack_eventpoll.c +++ /dev/null @@ -1,1215 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "nstack_eventpoll.h" -#include "nstack_log.h" -#include "nsfw_recycle_api.h" -#include "nstack_securec.h" -#include "nstack_module.h" -#include "nstack_sockops.h" -#include "nsfw_mem_api.h" -#include "nstack_fd_mng.h" -#include "nstack.h" -#include "nstack_dmm_adpt.h" - -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C"{ -/* *INDENT-ON* */ -#endif /* __cplusplus */ - -#define NSTACK_EP_TRIGGLE(epFD, proFD, modInx, triggle_ops, event, pdata, ret) \ - if (nstack_extern_deal(modInx).ep_ctl != NULL) \ - { \ - ret = nstack_extern_deal(modInx).ep_ctl((epFD), (proFD), (triggle_ops), (event), pdata); \ - } - -#define nstack_ep_getEvt(epFD, profd, modInx, events, ret) \ - if (nstack_extern_deal(modInx).ep_getevt != NULL)\ - { \ - ret |= nstack_extern_deal(modInx).ep_getevt((epFD), (profd), (events)); \ - } - -#define NSEP_IS_SOCK_VALID(_sock) ((_sock) >= 0 && (u32_t)(_sock) < NSTACK_KERNEL_FD_MAX) - -/*add event to rdlist if event have come in*/ -void -nsep_ctl_event_add (struct epitem *epi, struct eventpoll *ep, - int triggle_ops, unsigned int events) -{ - switch (triggle_ops) - { - case nstack_ep_triggle_add: - if (events & epi->event.events) - { - sys_arch_lock_with_pid (&ep->lock); - - if (!EP_HLIST_NODE_LINKED (&epi->rdllink)) - { - ep_hlist_add_tail (&ep->rdlist, &epi->rdllink); - } - - sys_sem_s_signal (&ep->lock); - sem_post (&ep->waitSem); - } - - break; - - case nstack_ep_triggle_mod: - sys_arch_lock_with_pid (&ep->lock); - - if (events & epi->event.events) - { - if (!EP_HLIST_NODE_LINKED (&epi->rdllink)) - { - ep_hlist_add_tail (&ep->rdlist, &epi->rdllink); - sem_post (&ep->waitSem); - } - } - else - { - if (EP_HLIST_NODE_LINKED (&epi->rdllink) - && (epi->event.events & EPOLLET)) - { - ep_hlist_del (&ep->rdlist, &epi->rdllink); - } - } - - sys_sem_s_signal (&ep->lock); - break; - default: - break; - } - - return; -} - -/* - * Triggle epoll events of stack - * ep - eventpoll instance - * fdInf - file descriptor of stack - * triggle_ops - why triggle - */ -NSTACK_STATIC void -nsep_epctl_triggle (struct epitem *epi, nsep_epollInfo_t * info, - int triggle_ops) -{ - int modInx; - int protoFd = -1; - int epfd = 0; - int ret = 0; - struct eventpoll *ep = NULL; - nsep_epollInfo_t *epInfo = NULL; - - ep = ADDR_SHTOL (epi->ep); - epfd = ep->epfd; - epInfo = nsep_get_infoBySock (epfd); - - NSSOC_LOGINF ("info=%p,info->rmidx=%d,triggle_ops=%d", info, info->rmidx, - triggle_ops); - - /* Now need to triggle userspace network stack events after add operation */ - if (info->rmidx >= 0) - { - /* fix overflow type codex issue */ - if ((info->rmidx >= NSEP_SMOD_MAX) - || (info->rmidx >= NSTACK_MAX_MODULE_NUM)) - { - return; - } - - NSTACK_EP_TRIGGLE (epInfo->protoFD[info->rmidx], info->rlfd, - info->rmidx, triggle_ops, &(epi->event), info, ret); - - if ((ret >= 0) - && ((nstack_ep_triggle_add == triggle_ops) - || (nstack_ep_triggle_mod == triggle_ops))) - { - epi->revents = ret; - nsep_ctl_event_add (epi, ep, triggle_ops, epi->revents); - info->epaddflag |= (1 << info->rmidx); - } - NSSOC_LOGINF ("info=%p,module=%s,protoFd=%d,triggle_ops=%d, ret:%d", - info, nstack_get_module_name_by_idx (info->rmidx), - info->rlfd, triggle_ops, ret); - } - else - { - nstack_each_modInx (modInx) - { - protoFd = info->protoFD[modInx]; - - if (protoFd < 0) - { - continue; - } - NSTACK_EP_TRIGGLE (epInfo->protoFD[modInx], protoFd, modInx, - triggle_ops, &(epi->event), info, ret); - if ((ret >= 0) - && ((nstack_ep_triggle_add == triggle_ops) - || (nstack_ep_triggle_mod == triggle_ops))) - { - epi->revents |= ret; - nsep_ctl_event_add (epi, ep, triggle_ops, epi->revents); - info->epaddflag |= (1 << modInx); - } - NSSOC_LOGINF ("info=%p,module=%s,protoFd=%d,triggle_ops=%d, ret:%d", - info, nstack_get_module_name_by_idx (modInx), protoFd, - triggle_ops, ret); - } - } - return; -} - -NSTACK_STATIC void -nsep_rbtree_insert (struct eventpoll *ep, struct epitem *epi) -{ - struct ep_rb_node **p = &ep->rbr.rb_node, *parent = NULL; - struct epitem *epic; - u32_t loopCnt = 0; - - while (*p) - { - ++loopCnt; - if (loopCnt > NSTACK_MAX_EPITEM_NUM) - { - NSSOC_LOGERR ("Loop out of range!!!!"); - break; - } - - parent = (struct ep_rb_node *) ADDR_SHTOL (*p); - epic = ep_rb_entry (parent, struct epitem, rbn); - if (epi->fd > epic->fd) - { - p = &(parent->rb_right); - } - else - { - p = &(parent->rb_left); - } - } - - ep_rb_link_node (&epi->rbn, parent, p); - ep_rb_insert_color (&epi->rbn, &ep->rbr); -} - -/* - * This function is called by epctl_add , it will create one epitem of fd, and insert to eventpoll - */ -NSTACK_STATIC int -nsep_insert_node (struct eventpoll *ep, struct epoll_event *event, - nsep_epollInfo_t * fdInfo) -{ - struct epitem *epi; - - if (nsep_alloc_epitem (&epi)) - { - NSSOC_LOGERR ("Can't alloc epitem"); - errno = ENOMEM; - return -1; - } - - EP_HLIST_INIT_NODE (&epi->rdllink); - EP_HLIST_INIT_NODE (&epi->lkFDllink); - - epi->nwait = 0; - epi->ep = (struct eventpoll *) ADDR_LTOSH_EXT (ep); - epi->epInfo = (nsep_epollInfo_t *) ADDR_LTOSH_EXT (fdInfo); - epi->revents = 0; - epi->ovf_revents = 0; - epi->event = *event; - EP_LIST_INIT_NODE (&epi->fllink); - epi->revents = 0; - epi->fd = fdInfo->fd; - - /* Add the current item to the list of active epoll hook for this file - This should lock because file descriptor may be called by other eventpoll */ - - sys_arch_lock_with_pid (&fdInfo->epiLock); - ep_list_add_tail (&fdInfo->epiList, &epi->fllink); - epi->private_data = (void *) ADDR_LTOSH_EXT (fdInfo); - sys_sem_s_signal (&fdInfo->epiLock); - - /* Add epitem to eventpoll fd list, don't need lock here because epoll_ctl will lock before calling this function */ - nsep_rbtree_insert (ep, epi); - - /* Need to poll the events already stored in stack */ - nsep_epctl_triggle (epi, fdInfo, nstack_ep_triggle_add); - - NSSOC_LOGINF ("epfd=%d,ep=%p,fd=%d,epi=%p", ep->epfd, ep, fdInfo->fd, epi); - - return 0; -} - -NSTACK_STATIC int -nsep_isAddValid (int fd) -{ - - if (nstack_fix_fd_check ()) - { - return nstack_fix_fd_check ()(fd, STACK_FD_INVALID_CHECK); - } - return 0; -} - -int -nsep_epctl_add (struct eventpoll *ep, int fd, struct epoll_event *events) -{ - - int ret = 0; - - NSSOC_LOGINF ("epfd=%d,fd=%d,events=%u", ep->epfd, fd, events->events); - - nsep_epollInfo_t *fdInfo = nsep_get_infoBySock (fd); - - if (NULL == fdInfo) - { - if (0 == nsep_isAddValid (fd)) - { - NSSOC_LOGERR ("Invalid add check nfd=%d]", fd); - return -1; - } - if (-1 == nsep_alloc_infoWithSock (fd)) - { - NSSOC_LOGERR ("Can't alloc epInfo for nfd]nfd=%d", fd); - return -1; - } - nsep_set_infoProtoFD (fd, nstack_get_fix_mid (), fd); - fdInfo = nsep_get_infoBySock (fd); - } - - ret = nsep_insert_node (ep, events, fdInfo); - if (0 != ret) - { - NSSOC_LOGWAR ("insert fail]epfd=%d,fd=%d ", ep->epfd, fdInfo->fd); - return -1; - } - - return 0; -} - -int -nsep_epctl_del (struct eventpoll *ep, struct epitem *epi) -{ - int ret = 0; - - nsep_epollInfo_t *epInfo = - (nsep_epollInfo_t *) ADDR_SHTOL (epi->private_data); - NSSOC_LOGINF ("epfd=%d,fd=%d,epi=%p", ep->epfd, epi->fd, epi); // modify log format error - - nsep_epctl_triggle (epi, epInfo, nstack_ep_triggle_del); - - sys_arch_lock_with_pid (&epInfo->epiLock); - ep_list_del (&epInfo->epiList, &epi->fllink); - - sys_sem_s_signal (&epInfo->epiLock); - - sys_arch_lock_with_pid (&ep->lock); - ret = nstack_ep_unlink (ep, epi); - sys_sem_s_signal (&ep->lock); - nsep_free_epitem (epi); - - return ret; -} - -int -nsep_epctl_mod (struct eventpoll *ep, - nsep_epollInfo_t * epInfo, - struct epitem *epi, struct epoll_event *events) -{ - if (NULL == epInfo) - { - errno = EINVAL; - NSSOC_LOGWAR ("epfd=%d, intput epInfo is null err", ep->epfd); - return -1; - } - - NSSOC_LOGINF ("epfd=%d,fd=%d,events=%u", ep->epfd, epInfo->fd, - events->events); - - sys_arch_lock_with_pid (&ep->lock); - epi->event = *events; /* kernel tells me that I need to modify epi->event in lock context */ - sys_sem_s_signal (&ep->lock); - - nsep_epctl_triggle (epi, epInfo, nstack_ep_triggle_mod); - return 0; -} - -/* - * Called by nsep_ep_poll - * proccess the event in the list - */ -static int -nsep_events_proc (struct eventpoll *ep, - struct ep_node_list *nhead, - struct epoll_event *events, int maxevents, int *eventflag, - int num) -{ - struct ep_hlist_node *node = NULL; - struct epitem *epi = NULL; - struct ep_hlist_node *head = nhead->head; - int evt = 0; - - while (head) - { - node = head; - epi = ep_hlist_entry (node, struct epitem, rdllink); - head = (struct ep_hlist_node *) ADDR_SHTOL (node->next); - EP_HLIST_INIT_NODE (node); - - nsep_epollInfo_t *fdInfo = - (nsep_epollInfo_t *) ADDR_SHTOL (epi->private_data); - - if (fdInfo->rmidx != -1) - { - nstack_ep_getEvt (ep->epfd, fdInfo->rlfd, fdInfo->rmidx, - epi->event.events, (epi->revents)); - } - - if (epi->revents) - { - /*set the flag that already have event int the rdlist */ - if (eventflag && (fdInfo->rmidx >= 0) && (fdInfo->rmidx < num)) - { - eventflag[fdInfo->rmidx] = 1; - } - events[evt].events = epi->revents; - events[evt].data = epi->event.data; - NSSOC_LOGDBG ("Add event]epfd=%d,fd=%d,events=%u", ep->epfd, - epi->fd, events[evt].events); - evt++; - } - - if (0 != epi->revents && EPOLLET != (epi->event.events & EPOLLET)) - { - NSSOC_LOGDBG ("Add epi->rdllink,epfd=%d,fd=%d", ep->epfd, epi->fd); - ep_hlist_add_tail (&ep->rdlist, &epi->rdllink); - } - epi->revents = 0; - - if (evt >= maxevents) - break; - } - nhead->head = head; - if (!head) - { - nhead->tail = NULL; - } - return evt; -} - -/* - * Called by epoll_wait - * Wait until events come or timeout - */ -int -nsep_ep_poll (struct eventpoll *ep, struct epoll_event *events, int maxevents, - int *eventflag, int num) -{ - - struct ep_hlist_node *tail = NULL; - struct ep_hlist_node *head = NULL; - struct epitem *epi = NULL; - struct epitem *nepi = NULL; - struct ep_node_list nhead = { 0 }; - int evt = 0; - nsep_epollInfo_t *fdInfo = NULL; - - if (EP_HLIST_EMPTY (&ep->rdlist)) - { - NSSOC_LOGDBG ("ep->rdlist is Empty, epfd=%d", ep->epfd); - return 0; - } - - sys_arch_lock_with_pid (&ep->sem); - - if (EP_HLIST_EMPTY (&ep->rdlist)) - { - goto out; - } - - sys_arch_lock_with_pid (&ep->lock); - head = (struct ep_hlist_node *) ADDR_SHTOL (ep->rdlist.head); - if (!head) - { - sys_sem_s_signal (&ep->lock); - goto out; - } - nhead.head = (struct ep_hlist_node *) ADDR_SHTOL (head->next); - nhead.tail = (struct ep_hlist_node *) ADDR_SHTOL (ep->rdlist.tail); - /*unlink from ep->rdlist */ - EP_HLIST_INIT (&(ep->rdlist)); - ep->ovflist = NULL; - sys_sem_s_signal (&ep->lock); - - /*get event list */ - evt = nsep_events_proc (ep, &nhead, events, maxevents, eventflag, num); - - sys_arch_lock_with_pid (&ep->lock); - /*put rest epitem back to the rdlist */ - if (nhead.head) - { - tail = (struct ep_hlist_node *) ADDR_SHTOL (ep->rdlist.tail); - tail->next = (struct ep_hlist_node *) ADDR_LTOSH (nhead.head); - nhead.head->pprev = (struct ep_hlist_node **) ADDR_LTOSH (&tail->next); - ep->rdlist.tail = (struct ep_hlist_node *) ADDR_LTOSH (nhead.tail); - } - /*put the epitem in ep->ovflist to rdlist */ - for (nepi = (struct epitem *) ADDR_SHTOL (ep->ovflist); - (epi = nepi) != NULL; - nepi = (struct epitem *) ADDR_SHTOL (epi->next), epi->next = - NSEP_EP_UNACTIVE_PTR) - { - epi->revents |= epi->ovf_revents; - /*set the flag that already have event int the rdlist */ - fdInfo = (nsep_epollInfo_t *) ADDR_SHTOL (epi->private_data); - if (eventflag && fdInfo && (fdInfo->rmidx >= 0) - && (fdInfo->rmidx < num)) - { - eventflag[fdInfo->rmidx] = 1; - } - epi->ovf_revents = 0; - if (!EP_HLIST_NODE_LINKED (&epi->rdllink)) - { - ep_hlist_add_tail (&ep->rdlist, &epi->rdllink); - } - } - ep->ovflist = NSEP_EP_UNACTIVE_PTR; - sys_sem_s_signal (&ep->lock); -out: - sys_sem_s_signal (&ep->sem); - NSSOC_LOGDBG ("Return epfd=%d,evt=%d,EP_HLIST_EMPTY(&ep->rdlist)=%d", - ep->epfd, evt, EP_HLIST_EMPTY (&ep->rdlist)); - return evt; -} - -#define FREE_LIST_SIZE 128 -#ifdef FREE_LIST_SIZE -struct free_list -{ - struct free_list *next; - struct list_node *node[FREE_LIST_SIZE]; -}; -#endif - -void -nsep_remove_epfd (nsep_epollInfo_t * pinfo) -{ - pid_t pid = get_sys_pid (); - struct list_node *prenode = NULL; - struct list_node *nextnode = NULL; -#ifdef FREE_LIST_SIZE - struct free_list flist; - struct free_list *fcurr = &flist; -#else - struct list_node **node_arry = NULL; - int length = NSTACK_MAX_EPOLL_INFO_NUM * sizeof (struct list_node *); -#endif - struct epitem *epi = NULL; - struct epitem *tepi = NULL; - struct eventpoll *ep = NULL; - u32_t i = 0; - u32_t icnt = 0; - - if (!pinfo) - { - return; - } - /*malloc a block memory to store epitem node, do not use list for maybe free item */ -#ifdef FREE_LIST_SIZE - flist.next = 0; -#else - node_arry = (struct list_node **) malloc (length); - if (!node_arry) - { - NSSOC_LOGERR ("remove fd from ep malloc mem fail]fd=%d,ep=%p", - pinfo->fd, pinfo->ep); - return; - } - - int retVal = MEMSET_S (node_arry, length, 0, length); - if (EOK != retVal) - { - NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); - free (node_arry); - return; - } -#endif - sys_arch_lock_with_pid (&pinfo->epiLock); - /*list head must be not null */ - prenode = (struct list_node *) ADDR_SHTOL (pinfo->epiList.head); - nextnode = (struct list_node *) ADDR_SHTOL (prenode->next); - icnt = 0; - - /*find all node that pid is belong to itself */ - while (nextnode) - { - if (++i > NSTACK_MAX_EPOLL_INFO_NUM) - { - /*record the exception log */ - NSSOC_LOGERR ("error maybe happen]free pinfo=%p", pinfo); - break; - } - epi = ep_list_entry (nextnode, struct epitem, fllink); - if (pid == epi->pid) - { - prenode->next = nextnode->next; - nextnode->next = NULL; - /*put into release list */ -#ifdef FREE_LIST_SIZE - if ((icnt % FREE_LIST_SIZE) == 0 && icnt) - { - struct free_list *fnext = - (struct free_list *) malloc (sizeof (struct free_list)); - if (!fnext) - { - NSSOC_LOGERR ("Out of memory for freelist]fd=%d icnt=%u", - pinfo->fd, icnt); - break; - } - fnext->next = NULL; - fcurr->next = fnext; - fcurr = fnext; - } - fcurr->node[icnt % FREE_LIST_SIZE] = nextnode; -#else - node_arry[icnt] = nextnode; -#endif - icnt++; - } - else - { - prenode = nextnode; - } - nextnode = (struct list_node *) ADDR_SHTOL (prenode->next); - } - - sys_sem_s_signal (&pinfo->epiLock); - - /*free all epitem */ -#ifdef FREE_LIST_SIZE - fcurr = &flist; -#endif - for (i = 0; i < icnt; i++) - { -#ifdef FREE_LIST_SIZE - if ((i % FREE_LIST_SIZE) == 0 && i) - { - fcurr = fcurr->next; - if (fcurr == NULL) - { - NSSOC_LOGERR ("freelist invalid NULL, fd=%d icnt=%u i=%u", - pinfo->fd, icnt, i); - break; - } - } - epi = - ep_list_entry (fcurr->node[i % FREE_LIST_SIZE], struct epitem, - fllink); -#else - epi = ep_list_entry (node_arry[i], struct epitem, fllink); -#endif - ep = (struct eventpoll *) ADDR_SHTOL (epi->ep); - if (ep) - { - sys_arch_lock_with_pid (&ep->sem); - /* Here don't use epi you find before, use fd and ep to find the epi again.that is multithread safe */ - tepi = nsep_find_ep (ep, pinfo->fd); - /*record the exception log */ - if (epi != tepi) - { - NSSOC_LOGERR ("remove fd:%d epi:%p tepi:%p erro maybe happen", - pinfo->fd, epi, tepi); - } - /*if tepi is null, epi maybe free by nsep_close_epfd, so no need to free again */ - if (tepi) - { - nsep_epctl_triggle (tepi, pinfo, nstack_ep_triggle_del); - sys_arch_lock_with_pid (&ep->lock); - (void) nstack_ep_unlink (ep, tepi); - sys_sem_s_signal (&ep->lock); - - nsep_free_epitem (epi); - } - sys_sem_s_signal (&ep->sem); - } - } -#ifdef FREE_LIST_SIZE - for (fcurr = flist.next; fcurr; fcurr = flist.next) - { - flist.next = fcurr->next; - free (fcurr); - } -#else - free (node_arry); -#endif - return; -} - -void -nsep_close_epfd (struct eventpoll *ep) -{ - - if (!ep) - return; - - struct epitem *epi = NULL; - struct ep_rb_node *node = NULL; - - sys_arch_lock_with_pid (&ep->sem); - while ((node = ep_rb_first (&ep->rbr))) - { - - epi = ep_rb_entry (node, struct epitem, rbn); - int ret = nsep_epctl_del (ep, epi); - - if (ret) - { - NSSOC_LOGERR - ("nstack epctl del fail, will break to avoid dead loop]ep->fd=%d,epi->fd=%d", - ep->epfd, epi->fd); - break; - } - } - sys_sem_s_signal (&ep->sem); - nsep_free_eventpoll (ep); -} - -static inline int -nsp_epoll_close_kernel_fd (int sock, nsep_epollInfo_t * epInfo) -{ - NSSOC_LOGINF ("fd=%d,type=%d", sock, epInfo->fdtype); - int ret = 0; - nsep_remove_epfd (epInfo); - - u32_t pid = get_sys_pid (); - sys_arch_lock_with_pid (&epInfo->freeLock); - int left_count = nsep_del_last_pid (&epInfo->pidinfo, pid); - sys_sem_s_signal (&epInfo->freeLock); - if (-1 == left_count) - { - NSSOC_LOGERR ("pid not exist]fd=%d,type=%d,pid=%d", sock, - epInfo->fdtype, pid); - } - - if (0 == left_count) - { - ret = nsep_free_epinfo (epInfo); - NSSOC_LOGINF ("epinfo removed]fd=%d,type=%d", sock, epInfo->fdtype); - } - - return ret; -} - -static inline int -nsp_epoll_close_spl_fd (int sock, nsep_epollInfo_t * epInfo) -{ - NSSOC_LOGINF ("fd=%d,type=%d", sock, epInfo->fdtype); - nsep_remove_epfd (epInfo); - return 0; -} - -static inline int -nsp_epoll_close_ep_fd (int sock, nsep_epollInfo_t * epInfo) -{ - struct eventpoll *ep = ADDR_SHTOL (epInfo->ep); - u32_t pid = get_sys_pid (); - NSSOC_LOGINF ("fd:%d is epoll fd ep:%p]", sock, ep); - sys_arch_lock_with_pid (&epInfo->freeLock); - int left_count = nsep_del_last_pid (&epInfo->pidinfo, pid); - sys_sem_s_signal (&epInfo->freeLock); - if (0 == left_count) - { - epInfo->ep = NULL; - nsep_close_epfd (ep); - nsep_free_epinfo (epInfo); - } - return 0; -} - -int -nsep_epoll_close (int sock) -{ - int ret = 0; - int modInx = 0; - int flag = 0; - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (sock); - if (!epInfo) - { - NSSOC_LOGDBG ("epollsock close sock:%d is not exist", sock); - return 0; - } - - if (NSTACK_EPOL_FD == epInfo->fdtype) - { - ret = nsp_epoll_close_ep_fd (sock, epInfo); - nsep_set_infoSockMap (sock, NULL); - return ret; - } - - nsep_set_infoSockMap (sock, NULL); - - nstack_each_modInx (modInx) - { - if (0 == (epInfo->epaddflag & (1 << modInx))) - { - flag = 1; - } - } - /*if no stack reference the epinfo, just free epInfo, - *else wait until the stack closed completely - */ - if (0 == flag) - { - ret = nsp_epoll_close_kernel_fd (sock, epInfo); - } - else - { - ret = nsp_epoll_close_spl_fd (sock, epInfo); - } - return ret; -} - -void -nsep_set_infoSockMap (int sock, nsep_epollInfo_t * info) -{ - nsep_epollManager_t *manager = nsep_getManager (); - if (NULL == manager->infoSockMap) - return; - - if (sock < 0 || (u32_t) sock >= NSTACK_KERNEL_FD_MAX) - return; - - manager->infoSockMap[sock] = info; -} - -nsep_epollInfo_t * -nsep_get_infoBySock (int sock) -{ - nsep_epollManager_t *manager = nsep_getManager (); - if ((NULL == manager) || (NULL == manager->infoSockMap)) - return NULL; - - if (sock < 0 || (u32_t) sock >= NSTACK_KERNEL_FD_MAX) - return NULL; - - return manager->infoSockMap[sock]; -} - -int -nsep_alloc_infoWithSock (int nfd) -{ - - nsep_epollInfo_t *epInfo = NULL; - - if (!NSEP_IS_SOCK_VALID (nfd)) - { - return -1; - } - - if (-1 == nsep_alloc_epinfo (&epInfo)) - { - NSSOC_LOGERR ("Alloc share info fail,[return]"); - return -1; - } - - epInfo->fd = nfd; - - nsep_set_infoSockMap (nfd, epInfo); - - return 0; -} - -void -nsep_set_infoProtoFD (int fd, int modInx, int protoFD) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return; - - if (modInx < 0 || modInx >= NSTACK_MAX_MODULE_NUM) - return; - - epInfo->protoFD[modInx] = protoFD; -} - -int -nsep_get_infoProtoFD (int fd, int modInx) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return -1; - - return epInfo->protoFD[modInx]; -} - -void -nsep_set_infomdix (int fd, int rmidx) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return; - - epInfo->rmidx = rmidx; -} - -int -nsep_get_infoMidx (int fd) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return -1; - - return epInfo->rmidx; -} - -void -nsep_set_infoRlfd (int fd, int rlfd) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return; - - epInfo->rlfd = rlfd; -} - -int -nsep_get_infoRlfd (int fd) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return -1; - - return epInfo->rlfd; -} - -void -nsep_set_infoSleepTime (int fd, u32 sleepTime) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return; - - epInfo->sleepTime = sleepTime; -} - -int -nsep_get_infoSleepTime (int fd) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return -1; - - return epInfo->sleepTime; -} - -void -nsep_set_infoEp (int fd, struct eventpoll *ep) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return; - - epInfo->ep = (struct eventpoll *) ADDR_LTOSH (ep); - epInfo->fdtype = NSTACK_EPOL_FD; -} - -struct eventpoll * -nsep_get_infoEp (int fd) -{ - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (fd); - - if (NULL == epInfo) - return NULL; - - return (struct eventpoll *) ADDR_SHTOL (epInfo->ep); -} - -int -nsep_free_infoWithSock (int nfd) -{ - if ((u32_t) nfd >= NSTACK_KERNEL_FD_MAX || nfd < 0) - return -1; - - nsep_epollInfo_t *info = nsep_get_infoBySock (nfd); - - if (NULL == info) - return 0; - - nsep_set_infoSockMap (nfd, NULL); - - NSSOC_LOGDBG ("nsep_free_infoWithSock info:%p, nfd:%d", info, nfd); - /* If this not just used by linux, it should be freed in stack-x */ - if (-1 == nsep_free_epinfo (info)) - { - NSSOC_LOGERR ("Error to free ep info"); - return -1; - } - return 0; -} - -/** - * @Function nsep_init_infoSockMap - * @Description initial map of epoll info and socket - * @param none - * @return 0 on success, -1 on error - */ -int -nsep_init_infoSockMap () -{ - nsep_epollManager_t *manager = nsep_getManager (); - nsep_epollInfo_t **map = - (nsep_epollInfo_t **) malloc (NSTACK_KERNEL_FD_MAX * - sizeof (nsep_epollInfo_t *)); - - if (!map) - { - NSSOC_LOGERR ("malloc epInfoPool fail"); - return -1; - } - - u32_t iindex; - for (iindex = 0; iindex < NSTACK_KERNEL_FD_MAX; iindex++) - { - map[iindex] = NULL; - } - - manager->infoSockMap = map; - - return 0; -} - -NSTACK_STATIC mzone_handle -nsep_ring_lookup (char *name) -{ - if (NULL == name) - { - NSSOC_LOGERR ("param error]name=%p", name); - return NULL; - } - - nsfw_mem_name mem_name; - if (EOK != STRCPY_S (mem_name.aname, sizeof (mem_name.aname), name)) - { - NSSOC_LOGERR ("Error to lookup ring by name, strcpy fail]name=%s", - name); - return NULL; - } - mem_name.enowner = NSFW_PROC_MAIN; - mem_name.entype = NSFW_SHMEM; - - return nsfw_mem_ring_lookup (&mem_name); -} - -NSTACK_STATIC mzone_handle -nsep_attach_shmem (char *name) -{ - if (NULL == name) - { - NSSOC_LOGERR ("param error]name=%p", name); - return NULL; - } - - nsfw_mem_name mem_name; - int retVal = STRCPY_S (mem_name.aname, sizeof (mem_name.aname), name); - if (EOK != retVal) - { - NSSOC_LOGERR ("STRCPY_S failed]"); - return NULL; - } - mem_name.enowner = NSFW_PROC_MAIN; - mem_name.entype = NSFW_SHMEM; - - return nsfw_mem_zone_lookup (&mem_name); -} - -NSTACK_STATIC int -nsep_attach_infoMem () -{ - mzone_handle hdl = nsep_attach_shmem (MP_NSTACK_EPOLL_INFO_NAME); - if (NULL == hdl) - return -1; - - nsep_epollManager_t *manager = nsep_getManager (); - manager->infoPool.pool = (nsep_epollInfo_t *) hdl; - - hdl = nsep_ring_lookup (MP_NSTACK_EPINFO_RING_NAME); - if (NULL == hdl) - { - NSSOC_LOGERR ("Fail to lock up epoll info ring]name=%s", - MP_NSTACK_EPINFO_RING_NAME); - return -1; - } - - manager->infoPool.ring = hdl; - - return 0; -} - -NSTACK_STATIC int -nsep_attach_epItemMem () -{ - mzone_handle hdl = nsep_attach_shmem (MP_NSTACK_EPITEM_POOL); - if (NULL == hdl) - return -1; - - nsep_epollManager_t *manager = nsep_getManager (); - manager->epitemPool.pool = (struct epitem *) hdl; - - hdl = nsep_ring_lookup (MP_NSTACK_EPITEM_RING_NAME); - if (NULL == hdl) - { - NSSOC_LOGERR ("Fail to lock up epoll info ring]name=%s", - MP_NSTACK_EPITEM_RING_NAME); - return -1; - } - - manager->epitemPool.ring = hdl; - - return 0; -} - -NSTACK_STATIC int -nsep_attach_eventpollMem () -{ - mzone_handle hdl = nsep_attach_shmem (MP_NSTACK_EVENTPOLL_POOL); - if (NULL == hdl) - return -1; - - nsep_epollManager_t *manager = nsep_getManager (); - manager->epollPool.pool = (struct eventpoll *) hdl; - - hdl = nsep_ring_lookup (MP_NSTACK_EVENTPOOL_RING_NAME); - if (NULL == hdl) - { - NSSOC_LOGERR ("Fail to lock up epoll info ring]name=%s", - MP_NSTACK_EVENTPOOL_RING_NAME); - return -1; - } - - manager->epollPool.ring = hdl; - - return 0; -} - -/* epinfo add pid in parent */ -void -nsep_fork_parent_proc (u32_t ppid, u32_t cpid) -{ - nsep_epollManager_t *manager = nsep_getManager (); - if (NULL == manager->infoSockMap) - { - NSSOC_LOGERR ("infoSockMap is NULL]ppid=%d,cpid=%d", ppid, cpid); - return; - } - - nstack_fd_Inf *fdInf = NULL; - nsep_epollInfo_t *epinfo = NULL; - int pos; - for (pos = 0; (u32_t) pos < NSTACK_KERNEL_FD_MAX; pos++) - { - epinfo = manager->infoSockMap[pos]; - if (epinfo) - { - fdInf = nstack_getValidInf (pos); - if (fdInf) - { - if (((u32_t) (fdInf->type)) & SOCK_CLOEXEC) - { - NSSOC_LOGINF ("fd is SOCK_CLOEXEC]fd=%d,ppid=%d.cpid=%d", - pos, ppid, cpid); - continue; - } - } - - if (nsep_add_pid (&epinfo->pidinfo, cpid) != 0) - { - NSSOC_LOGERR ("epinfo add pid failed]fd=%d,ppid=%d.cpid=%d", - pos, ppid, cpid); - } - else - { - NSSOC_LOGDBG ("epinfo add pid ok]fd=%d,ppid=%d.cpid=%d", pos, - ppid, cpid); - } - } - } -} - -/* check is pid exist in child,if no,detach epinfo*/ -void -nsep_fork_child_proc (u32_t ppid) -{ - nsep_epollManager_t *manager = nsep_getManager (); - if (NULL == manager->infoSockMap) - { - NSSOC_LOGERR ("epinfi sockmap not be create"); - return; - } - - u32_t cpid = get_sys_pid (); - nsep_epollInfo_t *epinfo = NULL; - int pos; - for (pos = 0; (u32_t) pos < NSTACK_KERNEL_FD_MAX; pos++) - { - epinfo = manager->infoSockMap[pos]; - if (epinfo) - { - if (!nsep_is_pid_exist (&epinfo->pidinfo, cpid)) - { - NSSOC_LOGINF - ("unuse epinfo,happen in SOCK_CLOEXEC,!FD_OPEN,parent coredump]fd=%d,epinfo=%p,ppid=%d,cpid=%d", - pos, epinfo, ppid, cpid); - nsep_set_infoSockMap (pos, NULL); - } - } - } -} - -int -nsep_attach_memory () -{ - typedef int (*nsep_attachMemFunc_t) (void); - nsep_attachMemFunc_t attachFuncs[] = { nsep_attach_infoMem, - nsep_attach_epItemMem, - nsep_attach_eventpollMem - }; - - int i = 0; - for (i = 0; - i < (int) (sizeof (attachFuncs) / sizeof (nsep_attachMemFunc_t)); i++) - { - if (-1 == attachFuncs[i] ()) - return -1; - } - - return 0; -} - -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif /* __cplusplus */ diff --git a/src/nSocket/nstack/event/select/nstack_select.c b/src/nSocket/nstack/event/select/nstack_select.c index f61b326..b9db0d7 100644 --- a/src/nSocket/nstack/event/select/nstack_select.c +++ b/src/nSocket/nstack/event/select/nstack_select.c @@ -20,220 +20,231 @@ #include "nstack_select.h" #include "nstack_log.h" #include "nsfw_base_linux_api.h" - +#include "nstack.h" +#include "nstack_dmm_dfx.h" /*==============================================* * constants or macros define * *----------------------------------------------*/ #ifdef NSTACK_SELECT_MODULE +#define SELECT_FREE_FD_BITS(read_set, write_set, exp_set) do{\ + select_free((read_set)->fds_bits); \ + select_free((write_set)->fds_bits); \ + select_free((exp_set)->fds_bits); \ +}while(0) /*==============================================* * project-wide global variables * *----------------------------------------------*/ -extern void *nstack_select_thread (void *arg); +extern void *nstack_select_thread(void *arg); +pthread_t g_select_thread_id; /*************select module***************************/ struct select_module_info g_select_module = { - .inited = FALSE, + .inited = FALSE, }; -/*==============================================* - * routines' or functions' implementations * - *----------------------------------------------*/ -/***************************************************************************** -* Prototype : get_select_module -* Description : get_select_module -* Input : void -* Output : None -* Return Value : struct select_module_info * -* Calls : -* Called By : -*****************************************************************************/ -struct select_module_info * -get_select_module (void) +struct select_module_info *get_select_module(void) { - return &g_select_module; + return &g_select_module; } /*split comm seclet entry to child mod select*/ -/***************************************************************************** -* Prototype : select_cb_split_by_mod -* Description : select_cb_split_by_module -* Input : i32 nfds -* fd_set *readfd -* fd_set *writefd -* fd_set *exceptfd -* struct select_entry *entry -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_cb_split_by_mod (i32 nfds, - fd_set * readfd, - fd_set * writefd, - fd_set * exceptfd, struct select_entry * entry) +/*no need to check null pointer*/ + +i32 select_cb_split_by_mod(i32 nfds, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, struct select_entry * entry) { - i32 inx; - i32 i; - i32 fd; + i32 inx; + i32 i; + i32 fd; - for (i = 0; i < nfds; i++) + for (i = 0; i < nfds; i++) { - - /*not bound to any stack */ - for (inx = 0; inx < get_mode_num (); inx++) + /*not bound to any stack */ + for (inx = 0; inx < nstack_get_module_num(); inx++) { - if (!((readfd && FD_ISSET (i, readfd)) || - (writefd && FD_ISSET (i, writefd)) || - (exceptfd && FD_ISSET (i, exceptfd)))) + if (!((readfd && FD_ISSET(i, readfd)) || + (writefd && FD_ISSET(i, writefd)) || + (exceptfd && FD_ISSET(i, exceptfd)))) { - continue; + continue; } - fd = select_get_modfd (i, inx); - /*not create by nstack */ - if ((fd < 0) || (select_get_modindex (i) < 0)) + fd = select_get_modfd(i, inx); + /*not create by nstack */ + if ((fd < 0) || (select_get_modindex(i) < 0)) { - - if (inx != get_mode_linux_index ()) + if (inx != nstack_get_linux_mid()) { - continue; + continue; } - fd = i; - nssct_create (fd, fd, inx); + fd = i; + nssct_create(fd, fd, inx); /*do not need return value */ } - else + else { - if (select_get_modindex (i) != inx) - continue; + if (select_get_modindex(i) != inx) + { + continue; + } } - NSSOC_LOGDBG ("fd is available i= %d fd = %d index = %d\n", i, fd, - inx); - if ((readfd) && (FD_ISSET (i, readfd))) + + NSSOC_LOGDBG("fd is valiable i= %d fd = %d index = %d\n", i, fd, + inx); + if ((readfd) && (FD_ISSET(i, readfd))) { - NSTACK_FD_SET (fd, &(entry->cb[inx].nstack_readset)); - if (entry->cb[inx].count <= fd) - entry->cb[inx].count = fd + 1; + if (inx == nstack_get_linux_mid()) + { + FD_SET(fd, &(entry->cb[inx].readset)); + } + else + { + NSTACK_FD_SET(fd, &(entry->cb[inx].nstack_readset)); + } + if (entry->cb[inx].count <= fd) + { + entry->cb[inx].count = fd + 1; + } } - if ((writefd) && (FD_ISSET (i, writefd))) + if ((writefd) && (FD_ISSET(i, writefd))) { - NSTACK_FD_SET (fd, &(entry->cb[inx].nstack_writeset)); - if (entry->cb[inx].count <= fd) - entry->cb[inx].count = fd + 1; + if (inx == nstack_get_linux_mid()) + { + FD_SET(fd, &(entry->cb[inx].writeset)); + } + else + { + NSTACK_FD_SET(fd, &(entry->cb[inx].nstack_writeset)); + } + + if (entry->cb[inx].count <= fd) + { + entry->cb[inx].count = fd + 1; + } } - if ((exceptfd) && (FD_ISSET (i, exceptfd))) + if ((exceptfd) && (FD_ISSET(i, exceptfd))) { - NSTACK_FD_SET (fd, &(entry->cb[inx].nstack_exceptset)); - if (entry->cb[inx].count <= fd) - entry->cb[inx].count = fd + 1; + if (inx == nstack_get_linux_mid()) + { + FD_SET(fd, &(entry->cb[inx].exceptset)); + } + else + { + NSTACK_FD_SET(fd, &(entry->cb[inx].nstack_exceptset)); + } + + if (entry->cb[inx].count <= fd) + { + entry->cb[inx].count = fd + 1; + } } } } - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - if (entry->cb[inx].count > 0) + if (entry->cb[inx].count > 0) { - entry->info.set_num++; - entry->info.index = inx; + entry->info.set_num++; + entry->info.index = inx; } } - return TRUE; + return TRUE; } /***************************************************************************** * Prototype : select_add_cb -* Description : add cb to global list +* Description : add cb to gloab list * Input : struct select_entry *entry * Output : None * Return Value : i32 * Calls : * Called By : *****************************************************************************/ -i32 -select_add_cb (struct select_entry * entry) +i32 select_add_cb(struct select_entry * entry) { - if ((!entry)) + if ((!entry)) { - return FALSE; + return FALSE; } - select_spin_lock (&g_select_module.lock); + select_spin_lock(&g_select_module.lock); - if (!g_select_module.entry_head) + if (!g_select_module.entry_head) { - g_select_module.entry_head = entry; - g_select_module.entry_tail = entry; - entry->next = NULL; - entry->prev = NULL; + g_select_module.entry_head = entry; + g_select_module.entry_tail = entry; + entry->next = NULL; + entry->prev = NULL; } - else + else { - g_select_module.entry_tail->next = entry; - entry->prev = g_select_module.entry_tail; - g_select_module.entry_tail = entry; - entry->next = NULL; + g_select_module.entry_tail->next = entry; + entry->prev = g_select_module.entry_tail; + g_select_module.entry_tail = entry; + entry->next = NULL; } - select_spin_unlock (&g_select_module.lock); - select_sem_post (&g_select_module.sem); - return TRUE; + select_spin_unlock(&g_select_module.lock); + select_sem_post(&g_select_module.sem); /*do not need return value */ + return TRUE; } /***************************************************************************** * Prototype : select_rm_cb -* Description : rm the cb from global list +* Description : rm the cb from gloab list * Input : struct select_entry *entry * Output : None * Return Value : i32 * Calls : * Called By : *****************************************************************************/ -i32 -select_rm_cb (struct select_entry * entry) +i32 select_rm_cb(struct select_entry * entry) { - if (!entry) + if (!entry) { - return FALSE; + return FALSE; } - select_spin_lock (&g_select_module.lock); + select_spin_lock(&g_select_module.lock); - if (g_select_module.entry_head == entry) + if (g_select_module.entry_head == entry) { - g_select_module.entry_head = entry->next; + g_select_module.entry_head = entry->next; } - else if (entry->prev) + else if (entry->prev) { - entry->prev->next = entry->next; + entry->prev->next = entry->next; } - if (g_select_module.entry_tail == entry) + if (g_select_module.entry_tail == entry) { - g_select_module.entry_tail = entry->prev; + g_select_module.entry_tail = entry->prev; } - else if (entry->next) + else if (entry->next) { - entry->next->prev = entry->prev; + entry->next->prev = entry->prev; } - entry->next = NULL; - entry->prev = NULL; + entry->next = NULL; + entry->prev = NULL; - select_spin_unlock (&g_select_module.lock); - return TRUE; + select_spin_unlock(&g_select_module.lock); + return TRUE; } -/*get fd set from entry*/ +/*get fd set from entrys*/ +/*no need to check null pointer*/ /***************************************************************************** * Prototype : select_thread_get_fdset -* Description : get module listening fd form global list +* Description : get module listening fd form gloab list * Input : nstack_fd_set *readfd * nstack_fd_set *writefd * nstack_fd_set *exceptfd @@ -244,55 +255,118 @@ select_rm_cb (struct select_entry * entry) * Calls : * Called By : *****************************************************************************/ -i32 -select_thread_get_fdset (nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, - struct select_module_info * module, i32 inx) +i32 select_thread_get_fdset(nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, + struct select_module_info * module, i32 inx) { - struct select_entry *tmp; - i32 nfds = 0; - int retVal; + struct select_entry *tmp; + i32 nfds = 0; + int retVal; - if (!module) + if (!module) { - return FALSE; + return FALSE; } - retVal = NSTACK_FD_ZERO (readfd); - retVal |= NSTACK_FD_ZERO (writefd); - retVal |= NSTACK_FD_ZERO (exceptfd); - if (EOK != retVal) + u32 fd_set_size = + sizeof(unsigned char) * ((NSTACK_SELECT_MAX_FD + 7) / 8); + + /*add return value check */ + retVal = NSTACK_FD_ZERO(readfd, fd_set_size); + retVal |= NSTACK_FD_ZERO(writefd, fd_set_size); + retVal |= NSTACK_FD_ZERO(exceptfd, fd_set_size); + if (EOK != retVal) { - NSSOC_LOGERR ("NSTACK_FD_ZERO MEMSET_S failed]ret=%d", retVal); - return FALSE; + NSSOC_LOGERR("NSTACK_FD_ZERO memset_s failed]ret=%d", retVal); + return FALSE; } - select_spin_lock (&module->lock); - for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) { - if (tmp->cb[inx].count <= 0) + if (tmp->cb[inx].count <= 0) { - continue; + continue; } - NSTACK_FD_OR (readfd, &tmp->cb[inx].nstack_readset); - NSTACK_FD_OR (writefd, &tmp->cb[inx].nstack_writeset); - NSTACK_FD_OR (exceptfd, &tmp->cb[inx].nstack_exceptset); - if (nfds < tmp->cb[inx].count) + NSTACK_FD_OR(readfd, &tmp->cb[inx].nstack_readset); + NSTACK_FD_OR(writefd, &tmp->cb[inx].nstack_writeset); + NSTACK_FD_OR(exceptfd, &tmp->cb[inx].nstack_exceptset); + if (nfds < tmp->cb[inx].count) { - nfds = tmp->cb[inx].count; + nfds = tmp->cb[inx].count; } } - select_spin_unlock (&module->lock); + select_spin_unlock(&module->lock); - return nfds; + return nfds; +} + +/*no need to check null pointer*/ + +i32 select_thread_get_fdset_linux(fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, + struct select_module_info * module, i32 inx) +{ + struct select_entry *tmp; + i32 nfds = 0; + int i; + + if (!module) + { + return 0; + } + + FD_ZERO(readfd); + FD_ZERO(writefd); + FD_ZERO(exceptfd); + + select_spin_lock(&module->lock); + + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + { + if (tmp->cb[inx].count <= 0) + { + continue; + } + + /*need to diff linux and daemon-stack */ + for (i = 0; i < __FD_SETSIZE; i++) + { + if (FD_ISSET(i, &tmp->cb[inx].readset)) + { + FD_SET(i, readfd); + } + + if (FD_ISSET(i, &tmp->cb[inx].writeset)) + { + FD_SET(i, writefd); + } + + if (FD_ISSET(i, &tmp->cb[inx].exceptset)) + { + FD_SET(i, exceptfd); + } + } + /*need to diff linux and daemon-stack */ + + if (nfds < tmp->cb[inx].count) + { + nfds = tmp->cb[inx].count; + } + } + + select_spin_unlock(&module->lock); + + return nfds; } /***************************************************************************** * Prototype : select_thread_set_fdset -* Description : set ready event to global list +* Description : set ready event to gloab list * Input : i32 nfds * nstack_fd_set *readfd * nstack_fd_set *writefd @@ -305,186 +379,402 @@ select_thread_get_fdset (nstack_fd_set * readfd, * Calls : * Called By : *****************************************************************************/ -i32 -select_thread_set_fdset (i32 nfds, - nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, - struct select_module_info * module, i32 inx, i32 err) +i32 select_thread_set_fdset(i32 nfds, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, + struct select_module_info * module, + i32 inx, i32 err) { - struct select_entry *tmp; + struct select_entry *tmp; - if (!module) + if (!module) { - return FALSE; + return FALSE; } - select_spin_lock (&module->lock); - for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) { - if (tmp->cb[inx].count <= 0) + if (tmp->cb[inx].count <= 0) { - continue; + continue; } - if (nfds < 0) + if (nfds < 0) { - tmp->ready.readyset = nfds; - tmp->ready.select_errno = err; - continue; + tmp->ready.readyset = nfds; + tmp->ready.select_errno = err; + continue; } - NSSOC_LOGDBG ("readyset=%d,index=%d", tmp->ready.readyset, inx); - entry_module_fdset (tmp, nfds, readfd, writefd, exceptfd, inx); + NSSOC_LOGDBG("readyset=%d,index=%d", tmp->ready.readyset, inx); + entry_module_fdset(tmp, nfds, readfd, writefd, exceptfd, inx); } - select_spin_unlock (&module->lock); - return TRUE; + select_spin_unlock(&module->lock); + return TRUE; } +NSTACK_STATIC inline void entry_mod_fdset_linux(int fd, int idx, int inx, + struct select_entry *entry, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd) +{ + if (FD_ISSET(idx, readfd) && FD_ISSET(idx, &entry->cb[inx].readset)) + { + FD_SET(fd, &entry->ready.readset); + entry->ready.count++; + NSSOC_LOGDBG("readyset is %d", entry->ready.readyset); + } + + if (FD_ISSET(idx, writefd) && FD_ISSET(idx, &entry->cb[inx].writeset)) + { + FD_SET(fd, &entry->ready.writeset); + entry->ready.count++; + NSSOC_LOGDBG("writeset is %d", entry->ready.readyset); + } + + if (FD_ISSET(idx, exceptfd) && FD_ISSET(idx, &entry->cb[inx].exceptset)) + { + FD_SET(fd, &entry->ready.exceptset); + entry->ready.count++; + NSSOC_LOGDBG("exceptset is %d", entry->ready.readyset); + } +} + +NSTACK_STATIC inline void entry_module_fdset_linux(struct select_entry + *entry, i32 fd_size, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, i32 inx) +{ + i32 i; + i32 fd; + + for (i = 0; i < fd_size; i++) + { + fd = select_get_commfd(i, inx); + if (fd < 0) + { + continue; + } + + entry_mod_fdset_linux(fd, i, inx, entry, readfd, writefd, exceptfd); + } +} + +i32 select_thread_set_fdset_linux(i32 nfds, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, + struct select_module_info *module, + i32 inx, i32 err) +{ + + struct select_entry *tmp; + + if (!module) + { + return FALSE; + } + + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + { + if (tmp->cb[inx].count <= 0) + { + continue; + } + + if (nfds < 0) + { + tmp->ready.readyset = nfds; + tmp->ready.select_errno = err; + continue; + } + NSSOC_LOGDBG("readyset=%d,index=%d", tmp->ready.readyset, inx); + entry_module_fdset_linux(tmp, nfds, readfd, writefd, exceptfd, inx); + } + select_spin_unlock(&module->lock); + return TRUE; + +} + +/*no need to check null pointer*/ /***************************************************************************** * Prototype : select_event_post -* Description : when event ready post sem to awake nstack_select +* Description : when event ready post sem to awaik nstack_select * Input : struct select_module_info *module * Output : None * Return Value : void * Calls : * Called By : *****************************************************************************/ -void -select_event_post (struct select_module_info *module) +void select_event_post(struct select_module_info *module) { - struct select_entry *tmp; - int inx; - select_spin_lock (&module->lock); - for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + struct select_entry *tmp; + int inx; + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) { - if ((tmp->ready.readyset != 0)) + if ((tmp->ready.readyset != 0)) { - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - tmp->cb[inx].count = 0; + tmp->cb[inx].count = 0; } - NSSOC_LOGDBG ("readyset=%d", tmp->ready.readyset); - select_sem_post (&tmp->sem); + NSSOC_LOGDBG("readyset=%d", tmp->ready.readyset); + select_sem_post(&tmp->sem); /*do not need return value */ } } - select_spin_unlock (&module->lock); + select_spin_unlock(&module->lock); } +/*no need to check null pointer*/ + /*set select_event function*/ -/***************************************************************************** -* Prototype : select_module_init -* Description : init select module -* Input : None -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_module_init () +i32 select_module_init() { - i32 i; - pthread_t select_thread_id; - i32 retval; + i32 i; + i32 retval; - if (fdmapping_init () < 0) + if (fdmapping_init() < 0) { - goto ERR_RET; + goto ERR_RET; } - g_select_module.default_mod = get_mode_linux_index (); - g_select_module.default_fun = nsfw_base_select; + g_select_module.default_mod = nstack_get_linux_mid(); + g_select_module.default_fun = nsfw_base_select; - /*regist select fun */ - for (i = 0; i < get_mode_num (); i++) + /*regist select fun */ + for (i = 0; i < nstack_get_module_num(); i++) { - g_select_module.get_select_fun_nonblock[i] = - nstack_module_ops (i)->pfselect; + g_select_module.get_select_fun_nonblock[i] = + nstack_module_ops(i)->pfselect; } - select_sem_init (&g_select_module.sem, 0, 0); - select_spin_lock_init (&g_select_module.lock); + select_sem_init(&g_select_module.sem, 0, 0); /*do not need return value */ + select_spin_lock_init(&g_select_module.lock); - if (pthread_create (&select_thread_id, NULL, nstack_select_thread, NULL)) + if (pthread_create(&g_select_thread_id, NULL, nstack_select_thread, NULL)) { - goto ERR_RET; + goto ERR_RET; } - retval = pthread_setname_np (select_thread_id, "nstack_select"); - if (retval) + retval = pthread_setname_np(g_select_thread_id, "nstack_select"); + if (retval) { - /*set thread name failed */ + /*set thread name failed */ } - g_select_module.inited = TRUE; - g_select_module.entry_head = g_select_module.entry_tail = NULL; - return TRUE; + g_select_module.inited = TRUE; + g_select_module.entry_head = g_select_module.entry_tail = NULL; + return TRUE; -ERR_RET: + ERR_RET: - return FALSE; + return FALSE; } -/***************************************************************************** -* Prototype : entry_module_fdset -* Description : set event -* Input : struct select_entry *entry -* i32 fd_size -* nstack_fd_set *readfd -* nstack_fd_set *writefd -* nstack_fd_set *exceptfd -* i32 inx -* Output : None -* Return Value : void -* Calls : -* Called By : -*****************************************************************************/ -void -entry_module_fdset (struct select_entry *entry, - i32 fd_size, - nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, i32 inx) +NSTACK_STATIC inline void entry_mod_fdset_nstack(int fd, int idx, int inx, + struct select_entry *entry, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd) { - i32 i; - i32 fd; + if (NSTACK_FD_ISSET(idx, readfd) + && NSTACK_FD_ISSET(idx, &entry->cb[inx].nstack_readset)) + { + FD_SET(fd, &entry->ready.readset); + entry->ready.count++; + NSSOC_LOGDBG("readyset is %d", entry->ready.readyset); + } - for (i = 0; i < fd_size; i++) + if (NSTACK_FD_ISSET(idx, writefd) + && NSTACK_FD_ISSET(idx, &entry->cb[inx].nstack_writeset)) { - fd = select_get_commfd (i, inx); - if (fd < 0) - { - continue; - } - if (NSTACK_FD_ISSET (i, readfd) - && NSTACK_FD_ISSET (i, &entry->cb[inx].nstack_readset)) - { - FD_SET (fd, &entry->ready.readset); - entry->ready.readyset++; - NSSOC_LOGDBG ("readyset is %d", entry->ready.readyset); - } + FD_SET(fd, &entry->ready.writeset); + entry->ready.count++; + NSSOC_LOGDBG("writeset is %d", entry->ready.readyset); + } - if (NSTACK_FD_ISSET (i, writefd) - && NSTACK_FD_ISSET (i, &entry->cb[inx].nstack_writeset)) - { - FD_SET (fd, &entry->ready.writeset); - entry->ready.readyset++; - NSSOC_LOGDBG ("writeset is %d", entry->ready.readyset); - } + if (NSTACK_FD_ISSET(idx, exceptfd) + && NSTACK_FD_ISSET(idx, &entry->cb[inx].nstack_exceptset)) + { + FD_SET(fd, &entry->ready.exceptset); + entry->ready.count++; + NSSOC_LOGDBG("exceptset is %d", entry->ready.readyset); + } +} - if (NSTACK_FD_ISSET (i, exceptfd) - && NSTACK_FD_ISSET (i, &entry->cb[inx].nstack_exceptset)) +/*no need to check null pointer*/ +void entry_module_fdset(struct select_entry *entry, + i32 fd_size, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, i32 inx) +{ + i32 i; + i32 fd; + + for (i = 0; i < fd_size; i++) + { + fd = select_get_commfd(i, inx); + if (fd < 0) { - FD_SET (fd, &entry->ready.exceptset); - entry->ready.readyset++; - NSSOC_LOGDBG ("exceptset is %d", entry->ready.readyset); + continue; } + + entry_mod_fdset_nstack(fd, i, inx, entry, readfd, writefd, exceptfd); } +} +NSTACK_STATIC inline int nstack_fd_copy(nstack_fd_set * psrc, + nstack_fd_set * pdst, u32 size) +{ + return memcpy_s(pdst->fds_bits, size, psrc->fds_bits, size); +} + +NSTACK_STATIC inline int alloc_and_init_fd_set(nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, + struct select_cb_p *select_cb) +{ + int ret = 0; + u32 fds_bits_size = + sizeof(unsigned char) * ((NSTACK_SELECT_MAX_FD + 7) >> 3); + + readfd->fds_bits = select_fd_set_bits_alloc(); + writefd->fds_bits = select_fd_set_bits_alloc(); + exceptfd->fds_bits = select_fd_set_bits_alloc(); + if (!readfd->fds_bits || !writefd->fds_bits || !exceptfd->fds_bits) + { + return -1; + } + + ret |= + nstack_fd_copy(&(select_cb->nstack_readset), readfd, fds_bits_size); + ret |= + nstack_fd_copy(&(select_cb->nstack_writeset), writefd, fds_bits_size); + ret |= + nstack_fd_copy(&(select_cb->nstack_exceptset), exceptfd, + fds_bits_size); + if (EOK != ret) + { + return -1; + } + + return 0; +} + +NSTACK_STATIC inline i32 select_scan_linux(struct select_entry * entry, + int inx) +{ + i32 fd_size; + i32 ready; + fd_set readfd; + fd_set writefd; + fd_set exceptfd; + struct timeval timeout; + + fd_size = entry->cb[inx].count; + if (!g_select_module.get_select_fun_nonblock[inx] || (fd_size <= 0)) + { + return TRUE; + } + + readfd = (entry->cb[inx].readset); + writefd = (entry->cb[inx].writeset); + exceptfd = (entry->cb[inx].exceptset); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, &readfd, + &writefd, &exceptfd, + &timeout); + if (ready > 0) + { + entry_module_fdset_linux(entry, fd_size, &readfd, &writefd, + &exceptfd, inx); + } + else if (ready < 0) + { + entry->ready.count = ready; + entry->ready.select_errno = errno; + NSSOC_LOGERR("select failed index = %d", inx); + return FALSE; + } + + return TRUE; +} + +NSTACK_STATIC inline i32 select_scan_nstack(struct select_entry * entry, + int inx) +{ + i32 fd_size; + i32 ready; + i32 ret = TRUE; + nstack_fd_set *readfd = NULL; + nstack_fd_set *writefd = NULL; + nstack_fd_set *exceptfd = NULL; + struct timeval timeout; + + fd_size = entry->cb[inx].count; + if (!g_select_module.get_select_fun_nonblock[inx] || (fd_size <= 0)) + { + return TRUE; + } + + readfd = select_alloc(sizeof(nstack_fd_set)); + writefd = select_alloc(sizeof(nstack_fd_set)); + exceptfd = select_alloc(sizeof(nstack_fd_set)); + + if (!readfd || !writefd || !exceptfd) + { + NSSOC_LOGERR("malloc fd sets failed"); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return FALSE; + } + + if (alloc_and_init_fd_set(readfd, writefd, exceptfd, &(entry->cb[inx]))) + { + NSSOC_LOGERR("malloc fd bits failed"); + goto return_over; + ret = FALSE; + } + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, + (fd_set *) readfd, + (fd_set *) writefd, + (fd_set *) exceptfd, + &timeout); + if (ready > 0) + { + entry_module_fdset(entry, fd_size, readfd, writefd, exceptfd, inx); + } + else if (ready < 0) + { + entry->ready.count = ready; + entry->ready.select_errno = errno; + NSSOC_LOGERR("select failed index = %d", inx); + goto return_over; + ret = FALSE; + } + + return_over: + SELECT_FREE_FD_BITS(readfd, writefd, exceptfd); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return ret; } /***************************************************************************** @@ -496,100 +786,37 @@ entry_module_fdset (struct select_entry *entry, * Calls : * Called By : *****************************************************************************/ -i32 -select_scan (struct select_entry *entry) +i32 select_scan(struct select_entry * entry) { - i32 inx; - i32 fd_size; - i32 ready; - nstack_fd_set *readfd; - nstack_fd_set *writefd; - nstack_fd_set *exceptfd; - struct timeval timeout; - - readfd = malloc (sizeof (nstack_fd_set)); - writefd = malloc (sizeof (nstack_fd_set)); - exceptfd = malloc (sizeof (nstack_fd_set)); - if ((!readfd) || (!writefd) || (!exceptfd)) - { - NSPOL_LOGERR ("malloc nstack_fd_set fail"); - FREE_FD_SET (readfd, writefd, exceptfd); - return -1; - } - for (inx = 0; inx < get_mode_num (); inx++) - { - - *readfd = entry->cb[inx].nstack_readset; - *writefd = entry->cb[inx].nstack_writeset; - *exceptfd = entry->cb[inx].nstack_exceptset; - fd_size = entry->cb[inx].count; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - if ((g_select_module.get_select_fun_nonblock[inx]) && (fd_size > 0)) + i32 inx; + int ret = 0; + + for (inx = 0; inx < nstack_get_module_num(); inx++) + { + if (inx == nstack_get_linux_mid()) { - ready = - g_select_module.get_select_fun_nonblock[inx] (fd_size, - (fd_set *) readfd, - (fd_set *) writefd, - (fd_set *) exceptfd, - &timeout); + ret = select_scan_linux(entry, inx); } - else + else { - continue; + ret = select_scan_nstack(entry, inx); } - if (ready > 0) + if (!ret) { - entry_module_fdset (entry, fd_size, readfd, writefd, exceptfd, inx); + return FALSE; } - else if (ready < 0) - { - entry->ready.readyset = ready; - entry->ready.select_errno = errno; - NSSOC_LOGERR ("select failed index = %d", inx); - FREE_FD_SET (readfd, writefd, exceptfd); - return FALSE; - } - } - FREE_FD_SET (readfd, writefd, exceptfd); - return TRUE; -} -/***************************************************************************** -* Prototype : lint_lock -* Description : avoid lint error -* Input : None -* Output : None -* Return Value : static inline void -* Calls : -* Called By : -*****************************************************************************/ -static inline void -lint_lock () -{ - return; + return TRUE; } -/***************************************************************************** -* Prototype : lint_unlock -* Description : avoid lint error -* Input : None -* Output : None -* Return Value : static inline void -* Calls : -* Called By : -*****************************************************************************/ -static inline void -lint_unlock () -{ - return; -} +/*no need to check null pointer*/ +/*try to get event form all modules */ /***************************************************************************** * Prototype : nstack_select_thread -* Description : if global list not null scaning all modules ,need to think +* Description : if gloab list not null scaning all modules ,need to think about block mod * Input : void *arg * Output : None @@ -597,100 +824,145 @@ lint_unlock () * Calls : * Called By : *****************************************************************************/ -void * -nstack_select_thread (void *arg) -{ - -#define SELECT_SLEEP_TIME 100 //us - i32 inx; - nstack_fd_set *readfd; - nstack_fd_set *writefd; - nstack_fd_set *exceptfd; - i32 fd_size; - i32 ready; - i32 sleep_time = SELECT_SLEEP_TIME; - struct timeval timeout; +void *nstack_select_thread(void *arg) +{ - lint_lock (); +#define SELECT_SLEEP_TIME 800 //us + + i32 inx; + nstack_fd_set *readfd; + nstack_fd_set *writefd; + nstack_fd_set *exceptfd; + fd_set rdfd; + fd_set wtfd; + fd_set expfd; + i32 fd_size; + i32 ready; + i32 sleep_time = SELECT_SLEEP_TIME; + struct timeval timeout; + int selet_errno; + + readfd = select_alloc(sizeof(nstack_fd_set)); + writefd = select_alloc(sizeof(nstack_fd_set)); + exceptfd = select_alloc(sizeof(nstack_fd_set)); + if ((!readfd) || (!writefd) || (!exceptfd)) + { + NSPOL_LOGERR("malloc nstack_fd_set fail"); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return NULL; + } - readfd = malloc (sizeof (nstack_fd_set)); - writefd = malloc (sizeof (nstack_fd_set)); - exceptfd = malloc (sizeof (nstack_fd_set)); - if ((!readfd) || (!writefd) || (!exceptfd)) + readfd->fds_bits = select_fd_set_bits_alloc(); + writefd->fds_bits = select_fd_set_bits_alloc(); + exceptfd->fds_bits = select_fd_set_bits_alloc(); + if ((!readfd->fds_bits) || (!writefd->fds_bits) || (!exceptfd->fds_bits)) { - NSPOL_LOGERR ("malloc nstack_fd_set fail"); - FREE_FD_SET (readfd, writefd, exceptfd); - lint_unlock (); - return NULL; + NSPOL_LOGERR("malloc fd_bits for nstack_fd_set fail"); + + SELECT_FREE_FD_BITS(readfd, writefd, exceptfd); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return NULL; } - /*used nonblock need add block mod later */ + /*used nonblock need add block mod later */ - for (;;) + for (;;) { - /*wait app calling select no cong cpu */ - if (!g_select_module.entry_head) + /*wait app calling select no cong cpu */ + if (!g_select_module.entry_head) { - select_sem_wait (&g_select_module.sem); + select_sem_wait(&g_select_module.sem); /*do not need return value */ } - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - fd_size = - select_thread_get_fdset (readfd, writefd, exceptfd, - &g_select_module, inx); - if (fd_size <= 0) + if (inx == nstack_get_linux_mid()) { - continue; - } + fd_size = + select_thread_get_fdset_linux(&rdfd, &wtfd, &expfd, + &g_select_module, inx); + if (fd_size <= 0) + continue; + if (g_select_module.get_select_fun_nonblock[inx]) + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, + (fd_set + *) & + rdfd, + (fd_set + *) & + wtfd, + (fd_set + *) & + expfd, + &timeout); + else + continue; + + if (ready > 0) + + select_thread_set_fdset_linux(fd_size, &rdfd, + &wtfd, &expfd, + &g_select_module, inx, 0); + else if (ready < 0) + { - if (g_select_module.get_select_fun_nonblock[inx]) - { - ready = - g_select_module.get_select_fun_nonblock[inx] (fd_size, - (fd_set *) - readfd, - (fd_set *) - writefd, - (fd_set *) - exceptfd, - &timeout); + selet_errno = errno; + select_thread_set_fdset_linux(fd_size, &rdfd, &wtfd, + &expfd, &g_select_module, + inx, selet_errno); + break; + } } - else + else { - continue; - } + fd_size = + select_thread_get_fdset(readfd, writefd, exceptfd, + &g_select_module, inx); + if (fd_size <= 0) + continue; + if (g_select_module.get_select_fun_nonblock[inx]) + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, + (fd_set + *) + readfd, + (fd_set + *) + writefd, + (fd_set + *) + exceptfd, + &timeout); + else + continue; + + if (ready > 0) + select_thread_set_fdset(fd_size, readfd, writefd, exceptfd, &g_select_module, inx, 0); /*do not need return value */ + else if (ready < 0) + { + selet_errno = errno; + select_thread_set_fdset(ready, readfd, writefd, exceptfd, &g_select_module, inx, selet_errno); /*do not need return value */ + break; + } - if (ready > 0) - { - select_thread_set_fdset (fd_size, readfd, writefd, exceptfd, - &g_select_module, inx, 0); - } - else if (ready < 0) - { - select_thread_set_fdset (ready, readfd, writefd, exceptfd, - &g_select_module, inx, errno); - NSSOC_LOGERR ("module[%d] select failed] ret = %d errno = %d", - inx, ready, errno); - lint_unlock (); - break; } } - select_event_post (&g_select_module); - timeout.tv_sec = 0; - timeout.tv_usec = sleep_time; - lint_unlock (); - /*use linux select for timer */ - nsfw_base_select (1, NULL, NULL, NULL, &timeout); + select_event_post(&g_select_module); + timeout.tv_sec = 0; + timeout.tv_usec = sleep_time; + /*use linux select for timer */ + nsfw_base_select(1, NULL, NULL, NULL, &timeout); + //sys_sleep_ns(0, sleep_time); //g_sem_sleep_time } } /***************************************************************************** * Prototype : nssct_create -* Description : create a select record for event fd +* Description : create a select record for eveny fd * Input : i32 cfd * i32 mfd * i32 inx @@ -699,15 +971,14 @@ nstack_select_thread (void *arg) * Calls : * Called By : *****************************************************************************/ -void -nssct_create (i32 cfd, i32 mfd, i32 inx) +void nssct_create(i32 cfd, i32 mfd, i32 inx) { - if (g_select_module.inited != TRUE) + if (g_select_module.inited != TRUE) { - return; + return; } - select_set_modfd (cfd, inx, mfd); - select_set_commfd (mfd, inx, cfd); + select_set_modfd(cfd, inx, mfd); /*do not need return value */ + select_set_commfd(mfd, inx, cfd); /*do not need return value */ } /***************************************************************************** @@ -720,17 +991,16 @@ nssct_create (i32 cfd, i32 mfd, i32 inx) * Calls : * Called By : *****************************************************************************/ -void -nssct_close (i32 cfd, i32 inx) +void nssct_close(i32 cfd, i32 inx) { - if (g_select_module.inited != TRUE) + if (g_select_module.inited != TRUE) { - return; + return; } - i32 mfd = select_get_modfd (cfd, inx); - select_set_modfd (cfd, inx, -1); - select_set_commfd (mfd, inx, -1); - select_set_index (cfd, -1); + i32 mfd = select_get_modfd(cfd, inx); + select_set_modfd(cfd, inx, -1); /*do not need return value */ + select_set_commfd(mfd, inx, -1); /*do not need return value */ + select_set_index(cfd, -1); /*do not need return value */ } /***************************************************************************** @@ -743,36 +1013,260 @@ nssct_close (i32 cfd, i32 inx) * Calls : * Called By : *****************************************************************************/ -void -nssct_set_index (i32 fd, i32 inx) +void nssct_set_index(i32 fd, i32 inx) +{ + if (g_select_module.inited != TRUE) + { + return; + } + select_set_index(fd, inx); /*do not need return value */ +} + +int select_scan_return_from_entry(fd_set * readfds, fd_set * writefds, + fd_set * exceptfds, + struct select_entry *entry) +{ + int ret; + if (readfds) + { + *readfds = entry->ready.readset; + } + if (writefds) + { + *writefds = entry->ready.writeset; + } + if (exceptfds) + { + *exceptfds = entry->ready.exceptset; + } + + ret = entry->ready.readyset; + if (ret < 0) + { + errno = entry->ready.select_errno; + } + return ret; +} + +void nstack_select_entry_free(struct select_entry *entry) +{ + int i; + + if (!entry) + return; + + for (i = 0; i < nstack_get_module_num(); i++) + { + + SELECT_FREE_FD_BITS(&entry->cb[i].nstack_readset, + &entry->cb[i].nstack_writeset, + &entry->cb[i].nstack_exceptset); + } + + SELECT_FREE_FD_BITS(&entry->ready.nstack_readset, + &entry->ready.nstack_writeset, + &entry->ready.nstack_exceptset); + +} + +void nstack_select_entry_alloc(struct select_entry **entry) { - if (g_select_module.inited != TRUE) + struct select_entry *tmp; + int i; + + tmp = select_alloc(sizeof(struct select_entry)); + if (!tmp) + return; + for (i = 0; i < nstack_get_module_num(); i++) + { + tmp->cb[i].nstack_readset.fds_bits = select_fd_set_bits_alloc(); + tmp->cb[i].nstack_writeset.fds_bits = select_fd_set_bits_alloc(); + tmp->cb[i].nstack_exceptset.fds_bits = select_fd_set_bits_alloc(); + if (!tmp->cb[i].nstack_readset.fds_bits || + !tmp->cb[i].nstack_writeset.fds_bits || + !tmp->cb[i].nstack_exceptset.fds_bits) + { + goto err_return; + } + } + + tmp->ready.nstack_readset.fds_bits = select_fd_set_bits_alloc(); + tmp->ready.nstack_writeset.fds_bits = select_fd_set_bits_alloc(); + tmp->ready.nstack_exceptset.fds_bits = select_fd_set_bits_alloc(); + if (!tmp->ready.nstack_readset.fds_bits || + !tmp->ready.nstack_writeset.fds_bits || + !tmp->ready.nstack_exceptset.fds_bits) { - return; + goto err_return; + } + + *entry = tmp; + return; + err_return: + nstack_select_entry_free(tmp); + *entry = NULL; +} + +void select_fail_stat(i32 nfds, + fd_set * readfd, fd_set * writefd, fd_set * exceptfd) +{ + i32 i; + i32 event_id = 0; + nstack_fd_Inf *fdInf = NULL; + + for (i = 0; i < nfds; i++) + { + + event_id = 0; + if (!((readfd && FD_ISSET(i, readfd)) || + (writefd && FD_ISSET(i, writefd)) || + (exceptfd && FD_ISSET(i, exceptfd)))) + { + continue; + } + + fdInf = nstack_get_valid_inf(i); + if ((NULL == fdInf) || !fdInf->ops + || (fdInf->rmidx != MOD_INDEX_FOR_STACKPOOL)) + { + continue; + } + if ((readfd) && (FD_ISSET(i, readfd))) + { + event_id |= EPOLLIN; + } + if ((writefd) && (FD_ISSET(i, writefd))) + { + event_id |= EPOLLOUT; + } + if ((exceptfd) && (FD_ISSET(i, exceptfd))) + { + event_id |= EPOLLERR; + } + nstack_dfx_state_update((u64) fdInf->rlfd, fdInf->rmidx, + DMM_APP_SELECT_FAIL, + (void *) ((u64_t) event_id)); } - select_set_index (fd, inx); } -i32 -select_module_init_child () +int nstack_select_processing(int nfds, fd_set * readfds, fd_set * writefds, + fd_set * exceptfds, struct timeval *timeout) { - pthread_t select_thread_id; - i32 retval; + int ret = -1; + struct select_module_info *select_module = get_select_module(); + struct select_entry *entry = NULL; - if (pthread_create (&select_thread_id, NULL, nstack_select_thread, NULL)) + nstack_select_entry_alloc(&entry); + if (NULL == entry) { - goto ERR_RET; + errno = ENOMEM; + NSSOC_LOGERR("select entry alloc fail"); + goto err_return; } + /* need init sem */ + select_sem_init(&entry->sem, 0, 0); /*do not need return value */ + + /* fix dead-code type */ + /*split select fd to each modules fd and save to entry */ + (void) select_cb_split_by_mod(nfds, readfds, writefds, exceptfds, entry); + + /*if all fd in default module we just calling it */ + if (entry->info.set_num <= 1) + { + + /*adapte linux */ + if ((select_module) + && (entry->info.index == select_module->default_mod)) + { + if (select_module->default_fun) + { + ret = + select_module->default_fun(nfds, readfds, writefds, + exceptfds, timeout); + } + else + { + ret = + nsfw_base_select(nfds, readfds, writefds, exceptfds, + timeout); + } + goto err_return; + } + } + + /*cheching if event ready or not */ + if (FALSE == select_scan(entry)) + { + NSSOC_LOGERR("select scan fail"); + goto err_return; + } + + if (entry->ready.readyset != 0) + { + goto scan_return; + } + + if (TIMEVAL_EQUAL_ZERO(timeout)) + { + goto scan_return; + } + + if (FALSE == select_add_cb(entry)) + { + errno = ENOMEM; + NSSOC_LOGERR("select entry add fail"); + goto err_return; + } + + if (NULL == timeout) + { + select_sem_wait(&entry->sem); /*do not need return value */ + } + else + { + long time_cost = 0; + long msec = 0; + if (nstack_timeval2msec(timeout, &msec)) + { + nstack_set_errno(EINVAL); + goto err_return; + } + ret = nstack_sem_timedwait(&entry->sem, msec, &time_cost); + if (ret < 0) + { + nstack_set_errno(EINVAL); + goto err_return; + } + + if (time_cost >= msec) + { + select_fail_stat(nfds, readfds, writefds, exceptfds); + timeout->tv_sec = 0; + timeout->tv_usec = 0; + } + else if (time_cost > 0) + { + msec = msec - time_cost; + timeout->tv_sec = msec / 1000; + timeout->tv_usec = (msec % 1000) * 1000; + } + } + + select_rm_cb(entry); /*do not need return value */ + + scan_return: + ret = select_scan_return_from_entry(readfds, writefds, exceptfds, entry); - retval = pthread_setname_np (select_thread_id, "nstack_select_child"); - if (retval) + err_return: + if (entry) { - /*set thread name failed */ + nstack_select_entry_free(entry); } - return TRUE; + NSSOC_LOGDBG + ("nfds=%d,readfds=%p,writefds=%p,exceptfds=%p,timeout=%p,ret=%d errno=%d", + nfds, readfds, writefds, exceptfds, timeout, ret, errno); -ERR_RET: - return FALSE; + return ret; } #endif /* NSTACK_SELECT_MODULE */ diff --git a/src/nSocket/nstack/event/select/select_adapt.c b/src/nSocket/nstack/event/select/select_adapt.c index a9858e8..f61d7c1 100644 --- a/src/nSocket/nstack/event/select/select_adapt.c +++ b/src/nSocket/nstack/event/select/select_adapt.c @@ -26,314 +26,199 @@ /*==============================================* * project-wide global variables * *----------------------------------------------*/ -i32 nstack_mod_fd[NSTACK_MAX_MODULE_NUM][NSTACK_SELECT_MAX_FD]; struct select_fd_map_inf g_select_fd_map; /*==============================================* * routines' or functions' implementations * *----------------------------------------------*/ -/***************************************************************************** -* Prototype : select_alloc -* Description : select_alloc -* Input : int size -* Output : None -* Return Value : void * -* Calls : -* Called By : -*****************************************************************************/ -void * -select_alloc (int size) +void *select_alloc(int size) { - char *p; - if (size <= 0) + char *p; + if (size <= 0) { - return NULL; + return NULL; } - p = malloc (size); - if (!p) + p = malloc(size); + if (!p) { - return NULL; + return NULL; } - if (EOK != MEMSET_S (p, size, 0, size)) + if (EOK != memset_s(p, size, 0, size)) { - free (p); - p = NULL; + free(p); + p = NULL; } - return p; + return p; } -/***************************************************************************** -* Prototype : select_free -* Description : select_free -* Input : char *p -* Output : None -* Return Value : void -* Calls : -* Called By : -*****************************************************************************/ -void -select_free (char *p) +/*point is set to NULL because it's freeed */ +void select_free(void *p) { - if (p) + if (p) { - free (p); - p = NULL; + free(p); + p = NULL; } } -/***************************************************************************** -* Prototype : get_select_fdinf -* Description : get_select_fdinf -* Input : i32 fd -* Output : None -* Return Value : struct select_comm_fd_map * -* Calls : -* Called By : -*****************************************************************************/ -struct select_comm_fd_map * -get_select_fdinf (i32 fd) +struct select_comm_fd_map *get_select_fdinf(i32 fd) { - if ((fd < 0) || (fd >= NSTACK_SELECT_MAX_FD)) + if ((fd < 0) || ((u32) fd >= NSTACK_SELECT_MAX_FD)) { - return NULL; + return NULL; } - return (&g_select_fd_map.fdinf[fd]); + return (&g_select_fd_map.fdinf[fd]); } -/***************************************************************************** -* Prototype : reset_select_fdinf -* Description : reset_select_fdinf -* Input : i32 fd -* Output : None -* Return Value : void -* Calls : -* Called By : -*****************************************************************************/ -void -reset_select_fdinf (i32 fd) +void reset_select_fdinf(i32 fd) { - i32 i; - struct select_comm_fd_map *fdinf = get_select_fdinf (fd); - if (NULL == fdinf) + i32 i; + struct select_comm_fd_map *fdinf = get_select_fdinf(fd); + /* fdinf is possible is null */ + if (NULL == fdinf) { - return; + return; } - fdinf->index = -1; - for (i = 0; i < NSTACK_MAX_MODULE_NUM; i++) + fdinf->index = -1; + for (i = 0; i < NSTACK_MAX_MODULE_NUM; i++) { - fdinf->mod_fd[i] = -1; + fdinf->mod_fd[i] = -1; } } -/***************************************************************************** -* Prototype : select_get_modfd -* Description : select_get_modfd -* Input : i32 fd -* i32 inx -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_get_modfd (i32 fd, i32 inx) +i32 select_get_modfd(i32 fd, i32 inx) { - if ((fd < 0) || (fd >= NSTACK_SELECT_MAX_FD)) + if ((fd < 0) || ((u32) fd >= NSTACK_SELECT_MAX_FD)) { - return -1; + return -1; } - if ((inx < 0)) + if ((inx < 0)) { - return -1; + return -1; } - if (!g_select_fd_map.fdinf) + if (!g_select_fd_map.fdinf) { - return FALSE; + return FALSE; } - return (g_select_fd_map.fdinf[fd].mod_fd[inx]); + return (g_select_fd_map.fdinf[fd].mod_fd[inx]); } -/***************************************************************************** -* Prototype : select_set_modfd -* Description : select_set_modfd -* Input : i32 fd -* i32 inx -* i32 modfd -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_set_modfd (i32 fd, i32 inx, i32 modfd) +i32 select_set_modfd(i32 fd, i32 inx, i32 modfd) { - if ((fd < 0) || (fd >= NSTACK_SELECT_MAX_FD)) + if ((fd < 0) || ((u32) fd >= NSTACK_SELECT_MAX_FD)) { - return -1; + return -1; } - if (!g_select_fd_map.fdinf) + if (!g_select_fd_map.fdinf) { - return FALSE; + return FALSE; } - g_select_fd_map.fdinf[fd].mod_fd[inx] = modfd; + g_select_fd_map.fdinf[fd].mod_fd[inx] = modfd; - return TRUE; + return TRUE; } -/***************************************************************************** -* Prototype : select_get_modindex -* Description : select_get_modindex -* Input : i32 fd -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_get_modindex (i32 fd) +i32 select_get_modindex(i32 fd) { - if ((fd < 0) || (fd >= NSTACK_SELECT_MAX_FD)) + if ((fd < 0) || ((u32) fd >= NSTACK_SELECT_MAX_FD)) { - return -1; + return -1; } - return g_select_fd_map.fdinf[fd].index; + return g_select_fd_map.fdinf[fd].index; } -/***************************************************************************** -* Prototype : select_get_commfd -* Description : select_get_commfd -* Input : i32 modfd -* i32 inx -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_get_commfd (i32 modfd, i32 inx) +i32 select_get_commfd(i32 modfd, i32 inx) { - if ((modfd < 0) || (modfd >= NSTACK_SELECT_MAX_FD)) + if ((modfd < 0) || ((u32) modfd >= NSTACK_SELECT_MAX_FD)) { - return -1; + return -1; } - return g_select_fd_map.modinf[inx].comm_fd[modfd]; + return g_select_fd_map.modinf[inx].comm_fd[modfd]; } -/***************************************************************************** -* Prototype : select_set_commfd -* Description : select_set_commfd -* Input : i32 modfd -* i32 inx -* i32 fd -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_set_commfd (i32 modfd, i32 inx, i32 fd) +i32 select_set_commfd(i32 modfd, i32 inx, i32 fd) { - if ((modfd < 0) || (modfd >= NSTACK_SELECT_MAX_FD)) + if ((modfd < 0) || ((u32) modfd >= NSTACK_SELECT_MAX_FD)) { - return -1; + return -1; } - if (!g_select_fd_map.modinf[inx].comm_fd) + if (!g_select_fd_map.modinf[inx].comm_fd) { - return FALSE; + return FALSE; } - g_select_fd_map.modinf[inx].comm_fd[modfd] = fd; + g_select_fd_map.modinf[inx].comm_fd[modfd] = fd; - return TRUE; + return TRUE; } -/***************************************************************************** -* Prototype : select_set_index -* Description : select_set_index -* Input : i32 fd -* i32 inx -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_set_index (i32 fd, i32 inx) +i32 select_set_index(i32 fd, i32 inx) { - if ((fd < 0) || (fd >= NSTACK_SELECT_MAX_FD)) + if ((fd < 0) || ((u32) fd >= NSTACK_SELECT_MAX_FD)) { - return -1; + return -1; } - if (!g_select_fd_map.fdinf) + if (!g_select_fd_map.fdinf) { - return FALSE; + return FALSE; } - g_select_fd_map.fdinf[fd].index = inx; - return TRUE; + g_select_fd_map.fdinf[fd].index = inx; + return TRUE; } -/***************************************************************************** -* Prototype : fdmapping_init -* Description : fdmapping_init -* Input : void -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -fdmapping_init (void) +i32 fdmapping_init(void) { - int ret = FALSE; - int i, inx; + int ret = FALSE; + int i, inx; - g_select_fd_map.fdinf = - (struct select_comm_fd_map *) - select_alloc (sizeof (struct select_comm_fd_map) * NSTACK_SELECT_MAX_FD); - if (NULL == g_select_fd_map.fdinf) + g_select_fd_map.fdinf = + (struct select_comm_fd_map *) + select_alloc(sizeof(struct select_comm_fd_map) * + NSTACK_SELECT_MAX_FD); + if (NULL == g_select_fd_map.fdinf) { - goto err_return; + goto err_return; } - for (i = 0; i < get_mode_num (); i++) + for (i = 0; i < nstack_get_module_num(); i++) { - g_select_fd_map.modinf[i].comm_fd = - (i32 *) select_alloc (sizeof (i32) * NSTACK_SELECT_MAX_FD); - if (NULL == g_select_fd_map.modinf[i].comm_fd) + g_select_fd_map.modinf[i].comm_fd = + (i32 *) select_alloc(sizeof(i32) * NSTACK_SELECT_MAX_FD); + if (NULL == g_select_fd_map.modinf[i].comm_fd) { - goto err_return; + goto err_return; } } - for (i = 0; i < NSTACK_SELECT_MAX_FD; i++) + u32 fd_idx = 0; + for (fd_idx = 0; fd_idx < NSTACK_SELECT_MAX_FD; fd_idx++) { - reset_select_fdinf (i); + reset_select_fdinf(fd_idx); } - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - for (i = 0; i < NSTACK_SELECT_MAX_FD; i++) + for (fd_idx = 0; fd_idx < NSTACK_SELECT_MAX_FD; fd_idx++) { - select_set_commfd (i, inx, -1); - + select_set_commfd(fd_idx, inx, -1); } } - ret = TRUE; - return ret; -err_return: + ret = TRUE; + return ret; + err_return: - select_free ((char *) g_select_fd_map.fdinf); - for (i = 0; i < get_mode_num (); i++) + select_free((char *) g_select_fd_map.fdinf); + for (i = 0; i < nstack_get_module_num(); i++) { - select_free ((char *) g_select_fd_map.modinf[i].comm_fd); + select_free((char *) g_select_fd_map.modinf[i].comm_fd); } - return ret; + return ret; } diff --git a/src/nSocket/nstack/nstack.c b/src/nSocket/nstack/nstack.c index 9d6a2ba..444f9fc 100644 --- a/src/nSocket/nstack/nstack.c +++ b/src/nSocket/nstack/nstack.c @@ -20,773 +20,889 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> -#include "common_mem_buf.h" -#include "common_mem_api.h" +#include <dlfcn.h> #include "nstack_eventpoll.h" #include "nstack_socket.h" #include "nstack_securec.h" -#include "nsfw_init.h" +#include "nsfw_init_api.h" #include "nstack_share_res.h" #include "nsfw_mgr_com_api.h" #include "nsfw_ps_mem_api.h" -#include "nsfw_fd_timer_api.h" #include "nsfw_ps_api.h" #include "nsfw_recycle_api.h" +#include "nsfw_maintain_api.h" #include "nstack_fd_mng.h" +#include "nstack_sem.h" +#include "nsfw_maintain_api.h" +#include "nstack_module.h" +#include "nsfw_mem_api.h" +#include "dmm_rwlock.h" +#include "nsfw_base_linux_api.h" +#include "nstack_dmm_dfx.h" #include "nstack_info_parse.h" -#include "nstack_dmm_adpt.h" #include "nstack_rd.h" -#include "nstack_module.h" -#include "nstack_select.h" -#include "common_func.h" -#define NSTACK_EVENT_MEN_MAXLEN (sizeof(struct eventpoll_pool) + NSTACK_MAX_EPOLL_NUM * sizeof(struct eventpoll_entry)) -#define NSTACK_EPITEM_MEN_MAXLEN (sizeof(struct epitem_pool) + NSTACK_MAX_EPITEM_NUM *sizeof(struct epitem_entry)) -/* *INDENT-OFF* */ +int nstack_dmm_dfx_init(nstack_proc_ops * ops); nStack_info_t g_nStackInfo = { - .hasInited = NSTACK_MODULE_INIT, - .fwInited = NSTACK_MODULE_INIT, - .moduleload = NSTACK_MODULE_INIT, - .load_mutex = PTHREAD_MUTEX_INITIALIZER, - .lk_sockPoll = NULL, - .pid = 0, - .fork_lock = {0}, - .ikernelfdmax = NSTACK_MAX_SOCK_NUM, - }; - -/*if this flag was set, maybe all socket interface called during initializing*/ -__thread int g_tloadflag = 0; - -extern u8 app_mode; - -/*check init stack*/ -#define NSTACK_INIT_STATE_CHECK_RET(state) do {\ - if ((state) == NSTACK_MODULE_SUCCESS) \ - { \ - return 0; \ - } \ - if ((state) == NSTACK_MODULE_FAIL) \ - { \ - return -1; \ - } \ -}while(0); - - - -int -nstack_timeval2msec (struct timeval *pTime, u64_t * msec) + .hasInited = NSTACK_MODULE_INIT, + .fwInited = NSTACK_MODULE_INIT, + .init_mutex = PTHREAD_MUTEX_INITIALIZER, + .lk_sockPool = NULL, +#ifndef KERNEL_FD_SUPPORT + .fdhead = 0, + .fdlock = {0}, +#endif + .pid = 0, + .fork_lock = {0}, + .ikernelfdmax = NSTACK_MAX_SOCK_NUM, +}; + +int nstack_timeval2msec(struct timeval *pTime, long *msec) { - if (pTime->tv_sec < 0 || pTime->tv_usec < 0) + if (pTime->tv_sec < 0 || pTime->tv_usec < 0) { - NSSOC_LOGERR ("time->tv_sec is negative"); - return -1; + NSSOC_LOGERR("time->tv_sec is nagative"); + return -1; } - if (NSTACK_MAX_U64_NUM / 1000 < (u64_t) pTime->tv_sec) + if (NSTACK_MAX_U64_NUM / 1000 < (u64_t) pTime->tv_sec) { - NSSOC_LOGERR ("tout.tv_sec is too large]tout.tv_sec=%lu", - pTime->tv_sec); - return -1; + NSSOC_LOGERR("tout.tv_sec is too large]tout.tv_sec=%ld", + pTime->tv_sec); + return -1; } - u64_t sec2msec = 1000 * pTime->tv_sec; - u64_t usec2msec = (u64_t) pTime->tv_usec / 1000; + long sec2msec = 1000 * pTime->tv_sec; + long usec2msec = pTime->tv_usec / 1000; - if (NSTACK_MAX_U64_NUM - sec2msec < usec2msec) + if (NSTACK_MAX_U64_NUM - sec2msec < usec2msec) { - NSSOC_LOGERR - ("nsec2msec plus sec2usec is too large]usec2msec=%lu,usec2msec=%lu", - usec2msec, sec2msec); - return -1; + NSSOC_LOGERR + ("nsec2msec plus sec2usec is too large]usec2msec=%lu,usec2msec=%lu", + usec2msec, sec2msec); + return -1; } - *msec = sec2msec + usec2msec; - return 0; + *msec = sec2msec + usec2msec; + return 0; } -int -nstack_current_time2msec (u64_t * msec) +int nstack_current_time2msec(long *msec) { - struct timespec tout; - if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &tout))) + struct timespec tout; + if (unlikely(0 != clock_gettime(CLOCK_MONOTONIC, &tout))) { - NSSOC_LOGERR ("Failed to get time, errno = %d", errno); + NSSOC_LOGERR("Failed to get time, errno=%d", errno); } - if (NSTACK_MAX_U64_NUM / 1000 < (u64_t) tout.tv_sec) + if (NSTACK_MAX_U64_NUM / 1000 < (u64_t) tout.tv_sec) { - NSSOC_LOGERR ("tout.tv_sec is too large]tout.tv_sec=%lu", tout.tv_sec); - return -1; + NSSOC_LOGERR("tout.tv_sec is too large]tout.tv_sec=%ld", tout.tv_sec); + return -1; } - u64_t sec2msec = 1000 * tout.tv_sec; - u64_t nsec2msec = (u64_t) tout.tv_nsec / 1000000; + long sec2msec = 1000 * tout.tv_sec; + long nsec2msec = tout.tv_nsec / 1000000; - if (NSTACK_MAX_U64_NUM - sec2msec < nsec2msec) + if (NSTACK_MAX_U64_NUM - sec2msec < nsec2msec) { - NSSOC_LOGERR - ("nsec2msec plus sec2usec is too large]nsec2msec=%lu,usec2msec=%lu", - nsec2msec, sec2msec); - return -1; + NSSOC_LOGERR + ("nsec2msec plus sec2usec is too large]nsec2msec=%lu,usec2msec=%lu", + nsec2msec, sec2msec); + return -1; } - *msec = sec2msec + nsec2msec; + *msec = sec2msec + nsec2msec; - return 0; + return 0; } - -int -nstack_sem_timedwait (sem_t * pSem, u64_t abs_timeout /*ms */ ) +/*epoll and select shouldnot get affected by system time change*/ +int nstack_sem_timedwait(sem_t * pSem, long abs_timeout /*ms */ , + long *mcost) { - int retVal; + int retVal; - u64_t starttime, endtime; + /* clock_gettime() get second variable is long, so here should use long */ + long starttime, endtime; #define FAST_SLEEP_TIME 10000 #define SLOW_SLEEP_TIME 500000 #define FAST_RETRY_COUNT 100 - unsigned int retry_count = 0; + unsigned int retry_count = 0; - if (nstack_current_time2msec (&starttime)) + if (abs_timeout < 0 || nstack_current_time2msec(&starttime)) { - errno = ETIMEDOUT; - return -1; + NSSOC_LOGERR("times out"); + errno = ETIMEDOUT; + return -1; } - while (1) + while (1) { - retVal = sem_trywait (pSem); + retVal = sem_trywait(pSem); - if (nstack_current_time2msec (&endtime)) - { - errno = ETIMEDOUT; - return -1; - } + if (nstack_current_time2msec(&endtime)) + { + errno = ETIMEDOUT; + return -1; + } - /*when get event we return the time cost */ - if (retVal == 0) - { - return (endtime - starttime); - } - /*when time out it return 0 */ - if (endtime < starttime || (endtime - starttime) > abs_timeout) - { - errno = ETIMEDOUT; - return abs_timeout; + /*when get event we return the time cost */ + if (retVal == 0) + { + *mcost = (endtime - starttime); + return 0; + } + /*when time out it return 0 */ + if (endtime < starttime || (endtime - starttime) > abs_timeout) + { + errno = ETIMEDOUT; + *mcost = abs_timeout; + return 0; + } + + /*app calling setsockopt to set time */ + if (retry_count < FAST_RETRY_COUNT) + { + sys_sleep_ns(0, FAST_SLEEP_TIME); + retry_count++; + } + else + { + sys_sleep_ns(0, SLOW_SLEEP_TIME); + } } - /* app calling setsockopt to set time */ - if (retry_count < FAST_RETRY_COUNT) +} + +NSTACK_STATIC inline char *get_ver_head(char *version) +{ + const char *split = " "; + char *tmp = NULL; + char *next_pos = NULL; + + tmp = strtok_s(version, split, &next_pos); +#ifndef SYSTEMC_LIB + if (NULL == tmp || NULL == next_pos) +#else + if (NULL == tmp) +#endif { - sys_sleep_ns (0, FAST_SLEEP_TIME); - retry_count++; + return NULL; } - else + + // version + tmp = strtok_s(next_pos, split, &next_pos); + if (NULL == tmp) { - sys_sleep_ns (0, SLOW_SLEEP_TIME); - } + return NULL; } + return tmp; } -/*epoll and select shouldnot get affected by system time change*/ -int -nstack_epoll_sem_timedwait (sem_t * pSem, u64_t abs_timeout /*ms */ , - long wait_time /*us */ ) +NSTACK_STATIC int match_version(char *nstack_ver, char *my_ver) { - int retVal; - - /* clock_gettime() get second variable is long, so here should use long */ - u64_t starttime, endtime; - -#define FAST_SLEEP_TIME 10000 -#define SLOW_SLEEP_TIME 500000 -#define FAST_RETRY_COUNT 100 - unsigned int retry_count = 0; - - if (nstack_current_time2msec (&starttime)) + if ((NULL == nstack_ver || 0 == nstack_ver[0]) || + (NULL == my_ver || 0 == my_ver[0])) { - errno = ETIMEDOUT; - return -1; + NSSOC_LOGERR("invalid input]"); + return 0; } - while (1) - { - retVal = sem_trywait (pSem); + char *nstack_ver_head = NULL; + char *my_ver_head = NULL; - if (retVal == 0) + char nstack_version[NSTACK_VERSION_LEN] = { 0 }; + char my_version[NSTACK_VERSION_LEN] = { 0 }; + + // !!!strtok_s will modify the original string, so use use temp for parameter + /*use strcpy_s instead of memcpy_s to avoid invalid memory visit */ + if (EOK != strcpy_s(nstack_version, sizeof(nstack_version), nstack_ver)) { - return retVal; + return 0; } - if (nstack_current_time2msec (&endtime)) + nstack_ver_head = get_ver_head(nstack_version); + if (NULL == nstack_ver_head) { - errno = ETIMEDOUT; - return -1; + return 0; } - if (endtime < starttime || (endtime - starttime) > abs_timeout) + /*use strcpy_s instead of memcpy_s to avoid invalid memory visit */ + if (EOK != strcpy_s(my_version, sizeof(my_version), my_ver)) { - errno = ETIMEDOUT; - return -1; + return 0; } - /*app calling setsockopt to set time */ - if (wait_time > 0) + my_ver_head = get_ver_head(my_version); + if (NULL == my_ver_head) { - long wait_sec; - long wait_nsec; - wait_sec = wait_time / 1000000; - wait_nsec = 1000 * (wait_time % 1000000); - sys_sleep_ns (wait_sec, wait_nsec); //g_sem_sleep_time + return 0; } - else if (retry_count < FAST_RETRY_COUNT) + + /* Out-of-Bounds Read (FORTIFY.Out-of-Bounds_Read) */ + if (strlen(my_ver_head) != strlen(nstack_ver_head)) { - sys_sleep_ns (0, FAST_SLEEP_TIME); - retry_count++; + /*should return 0 when failed */ + return 0; } - else + + if (0 != strncmp(nstack_ver_head, my_ver_head, strlen(nstack_ver_head))) /* Out-of-Bounds Read (FORTIFY.Out-of-Bounds_Read) */ { - sys_sleep_ns (0, SLOW_SLEEP_TIME); - } + return 0; } + return 1; } -NSTACK_STATIC inline char * -get_ver_head (char *version) +NSTACK_STATIC inline void set_unmatch_version(char *version, + unmatch_ver_info_t * + app_ver_info) { - const char *split = " "; - char *tmp = NULL; - char *next_pos = NULL; - - tmp = STRTOK_S (version, split, &next_pos); - if (NULL == tmp || NULL == next_pos) + int i = 0; + if (version == NULL || app_ver_info == NULL) { - return NULL; + return; } - // version - tmp = STRTOK_S (next_pos, split, &next_pos); - if (NULL == tmp) + for (; i < MAX_UNMATCH_VER_CNT; i++) { - return NULL; + if (app_ver_info[i].unmatch_count != 0) + { + if (0 == + strncmp(version, app_ver_info[i].lib_version, + NSTACK_VERSION_LEN - 1)) + { + app_ver_info[i].unmatch_count++; + return; + } + } + else + { + /* (1) use some fixed value but no effect (e506) (2) it don't contain any extra commas (e505) */ + if (__sync_bool_compare_and_swap + (&app_ver_info[i].unmatch_count, 0, 1)) + { + // use strncpy_s to instead the complex logic + //if version is too long, truncate it to ensure the copy success. so set 'count' to NSTACK_VERSION_LEN-1 + int retval = strncpy_s(app_ver_info[i].lib_version, + NSTACK_VERSION_LEN, version, + NSTACK_VERSION_LEN - 1); + if (EOK != retval) + { + NSSOC_LOGERR("strncpy_s failed]ret=%d", retval); + return; + } + + get_current_time(app_ver_info[i].first_time_stamp, + LOG_TIME_STAMP_LEN); + return; + } + } } - - return tmp; } -NSTACK_STATIC int -match_version (char *nstack_ver, char *my_ver) +NSTACK_STATIC inline int check_main_version() { - if ((NULL == nstack_ver || 0 == nstack_ver[0]) || - (NULL == my_ver || 0 == my_ver[0])) + char my_version[NSTACK_VERSION_LEN] = { 0 }; + nsfw_mem_name stname = + { NSFW_SHMEM, NSFW_PROC_MAIN, {NSTACK_VERSION_SHM} }; + g_nStackInfo.nstack_version = nsfw_mem_zone_lookup(&stname); + + if (NULL == g_nStackInfo.nstack_version) { - NSSOC_LOGERR ("invalid input]"); - return 0; + NSSOC_LOGERR("can not get nstack version."); + return 0; } + /* copy string should use strcpy_s */ + if (EOK != strcpy_s(my_version, sizeof(my_version), NSTACK_VERSION)) + { + NSSOC_LOGERR("strcpy_s failed"); + return 0; + } - if (0 != strncmp (nstack_ver, my_ver, 5)) + if (match_version(g_nStackInfo.nstack_version, my_version)) { - return 0; + return 1; } - return 1; + NSSOC_LOGERR("version not match]my version=%s, daemon-stack_version=%s", + my_version, g_nStackInfo.nstack_version); + + /* record unmatched app version in snapshot- */ + char *unmatch_app_version = + g_nStackInfo.nstack_version + NSTACK_VERSION_LEN; + + set_unmatch_version(my_version, + (unmatch_ver_info_t *) unmatch_app_version); + + return 0; } -NSTACK_STATIC inline void -set_unmatch_version (char *version, unmatch_ver_info_t * app_ver_info) +int nstack_init_shmem() { - int i = 0; - if (version == NULL || app_ver_info == NULL) - { - return; - } + int deploytype = nstack_get_deploy_type(); - for (; i < MAX_UNMATCH_VER_CNT; i++) - { - if (app_ver_info[i].unmatch_count != 0) + if ((deploytype != NSTACK_MODEL_TYPE1) + && (deploytype != NSTACK_MODEL_TYPE_SIMPLE_STACK)) { - if (0 == - strncmp (version, app_ver_info[i].lib_version, - NSTACK_VERSION_LEN - 1)) + if (nstack_attach_share_res() != 0) + { + return -1; + } + + if (-1 == nsep_attach_memory()) + { + return -1; + } + + if (-1 == ns_sync_sem_module_init(1, 0)) { - app_ver_info[i].unmatch_count++; - return; + return -1; } } - else + else { - if (__sync_bool_compare_and_swap (&app_ver_info[i].unmatch_count, 0, 1)) + if (nstack_init_share_res() != 0) { - int retval = - STRNCPY_S (app_ver_info[i].lib_version, NSTACK_VERSION_LEN, - version, NSTACK_VERSION_LEN - 1); - if (EOK != retval) + return -1; + } + + if (-1 == nsep_create_memory()) { - NSSOC_LOGERR ("STRNCPY_S failed]ret=%d", retval); - return; + return -1; } - get_current_time (app_ver_info[i].first_time_stamp, - LOG_TIME_STAMP_LEN); - return; + if (-1 == ns_sync_sem_module_init(0, 0)) + { + return -1; } } - } + + return 0; } -NSTACK_STATIC inline void -check_main_version () +/** + * This should be called only once + */ +NSTACK_STATIC int nstack_init_mem(void) { - char my_version[NSTACK_VERSION_LEN] = { 0 }; - nsfw_mem_name stname = { NSFW_SHMEM, NSFW_PROC_MAIN, {NSTACK_VERSION_SHM} }; - g_nStackInfo.nstack_version = nsfw_mem_zone_lookup (&stname); + int ret = ns_fail; + int deploytype = nstack_get_deploy_type(); - if (NULL == g_nStackInfo.nstack_version) + /* record unmatched app version- */ + /* check lib version match - */ + if ((!check_main_version()) && (deploytype != NSTACK_MODEL_TYPE1) + && (deploytype != NSTACK_MODEL_TYPE_SIMPLE_STACK)) { - NSSOC_LOGERR ("can not get nstack version."); - return; + NSSOC_LOGERR("check version failed"); + return ns_fail; } - if (EOK != STRCPY_S (my_version, sizeof (my_version), NSTACK_VERSION)) + ret = nstack_init_shmem(); + if (ns_success != ret) { - NSSOC_LOGERR ("STRCPY_S failed"); - return; + NSSOC_LOGERR("nstack init shmem fail"); + return ns_fail; } - if (match_version (g_nStackInfo.nstack_version, my_version)) + if (nstack_stack_module_init()) { - return; + NSSOC_LOGERR("module init failed!"); + goto INIT_NOT_DONE; } - NSSOC_LOGERR ("version not match]my version=%s, nStackMain_version=%s", - my_version, g_nStackInfo.nstack_version); - - /* record unmatched app version in snapshot */ - char *unmatch_app_version = - g_nStackInfo.nstack_version + NSTACK_VERSION_LEN; - - set_unmatch_version (my_version, - (unmatch_ver_info_t *) unmatch_app_version); -} - -int -nstack_init_shmem () -{ - - int deploytype = nstack_get_deploy_type (); - - if (deploytype != NSTACK_MODEL_TYPE1 && deploytype != NSTACK_MODEL_TYPE_SIMPLE_STACK ) + if (ns_success != nstack_rd_sys()) { - if (-1 == nsep_attach_memory ()) - { - return -1; + NSSOC_LOGERR("nstack rd sys fail"); + return ns_fail; } - if (nstack_attach_share_res () != 0) + /*init select mod */ + if (FALSE == select_module_init()) { - return -1; - } + goto INIT_NOT_DONE; } - else - { - if (nsep_create_memory () != 0) + if (nstack_dmm_dfx_init(nstack_fd_deal)) { - return -1; + goto INIT_NOT_DONE; } - if (nstack_init_share_res () != 0) + ret = ns_success; + /* The memory of the g_nStackInfo.lk_sockPool was not released in the exception */ + return ret; + INIT_NOT_DONE: + ret = ns_fail; + return ret; + +} + +void nstack_fork_fd_local_lock_info(nstack_fd_local_lock_info_t * local_lock) +{ + if (local_lock->fd_ref.counter > 1) /* after fork, if fd ref > 1, need set it to 1 */ { - return -1; - } + local_lock->fd_ref.counter = 1; } - return 0; + dmm_spin_init(&local_lock->close_lock); } +void nstack_reset_fd_local_lock_info(nstack_fd_local_lock_info_t * local_lock) +{ + atomic_set(&local_lock->fd_ref, 0); + dmm_spin_init(&local_lock->close_lock); + local_lock->fd_status = FD_CLOSE; +} -/** - * This should be called only once - */ -NSTACK_STATIC int -nstack_init_mem (void) +dmm_rwlock_t *get_fork_lock() +{ + return &g_nStackInfo.fork_lock; +} + +NSTACK_STATIC int nstack_init_fd_local_info() { - int ret = ns_fail; - int deploytype = nstack_get_deploy_type (); - /* record unmatched app version*/ - /* check lib version match - Begin */ - if (deploytype != NSTACK_MODEL_TYPE1 && deploytype != NSTACK_MODEL_TYPE_SIMPLE_STACK ) + int iindex = 0; + int ret; + nstack_fd_Inf *fdInf; + + g_nStackInfo.lk_sockPool = (nstack_fd_Inf *) malloc(NSTACK_KERNEL_FD_MAX * sizeof(nstack_fd_Inf)); /*malloc can be used */ + if (!g_nStackInfo.lk_sockPool) { - check_main_version (); + NSSOC_LOGERR("malloc nstack_fd_lock_info failed"); + return ns_fail; } - - ret = nstack_init_shmem (); - if (ns_success != ret) + ret = + memset_s(g_nStackInfo.lk_sockPool, + NSTACK_KERNEL_FD_MAX * sizeof(nstack_fd_Inf), 0, + NSTACK_KERNEL_FD_MAX * sizeof(nstack_fd_Inf)); + if (EOK != ret) { - NSSOC_LOGERR ("nstack init shmem fail"); - return ns_fail; + NSSOC_LOGERR("memset error"); + free(g_nStackInfo.lk_sockPool); /*free can be used */ + g_nStackInfo.lk_sockPool = NULL; + return ns_fail; } - /*rd info sys*/ - ret = nstack_rd_sys(); - if (ns_success != ret) - { - NSSOC_LOGERR("nstack rd sys fail"); - return ns_fail; - } - - (void)nstack_stack_module_init(); + for (iindex = 0; iindex < (int) NSTACK_KERNEL_FD_MAX; iindex++) + { + fdInf = &g_nStackInfo.lk_sockPool[iindex]; + nstack_reset_fd_inf(fdInf); +#ifndef KERNEL_FD_SUPPORT + fdInf->fd = iindex; + if (iindex == NSTACK_KERNEL_FD_MAX - 1) + { + fdInf->nxtfd = -1; + } + else + { + fdInf->nxtfd = iindex + 1; + } +#endif + } - /*init select mod*/ - if(FALSE == select_module_init()){ - return ns_fail; - } - return ns_success; - /* The memory of the g_nStackInfo.lk_sockPoll was not released in the exception*/ -} +#ifndef KERNEL_FD_SUPPORT + g_nStackInfo.fdhead = 0; + dmm_spin_init((dmm_spinlock_t *) & g_nStackInfo.fdlock); +#endif -void -nstack_fork_fd_local_lock_info (nstack_fd_local_lock_info_t * local_lock) -{ - if (local_lock->fd_ref.counter > 1) /* after fork, if fd ref > 1, need set it to 1 */ + if (-1 == + nsep_init_info_sock_map(NSTACK_KERNEL_FD_MAX, NSTACK_MAX_MODULE_NUM)) { - local_lock->fd_ref.counter = 1; + NSSOC_LOGERR("malloc epInfoPool fail"); + if (g_nStackInfo.lk_sockPool) + { + free(g_nStackInfo.lk_sockPool); + g_nStackInfo.lk_sockPool = NULL; + } + return ns_fail; } - common_mem_spinlock_init (&local_lock->close_lock); -} -void -nstack_reset_fd_local_lock_info (nstack_fd_local_lock_info_t * local_lock) -{ - atomic_set (&local_lock->fd_ref, 0); - common_mem_spinlock_init (&local_lock->close_lock); - local_lock->fd_status = FD_CLOSE; + return ns_success; } -common_mem_rwlock_t * -get_fork_lock () -{ - return &g_nStackInfo.fork_lock; -} +/*=========== get share config for app =============*/ -NSTACK_STATIC int -nstack_init_fd_local_info () +NSTACK_STATIC inline int get_share_config() { - int iindex = 0; - nstack_fd_Inf *fdInf; + static nsfw_mem_name g_cfg_mem_info = + { NSFW_SHMEM, NSFW_PROC_MAIN, NSTACK_SHARE_CONFIG }; + int deploytype = nstack_get_deploy_type(); - g_nStackInfo.lk_sockPoll = (nstack_fd_Inf *) malloc (NSTACK_KERNEL_FD_MAX * sizeof (nstack_fd_Inf)); - if (!g_nStackInfo.lk_sockPoll) + if ((deploytype == NSTACK_MODEL_TYPE1) + || (deploytype == NSTACK_MODEL_TYPE_SIMPLE_STACK)) { - NSSOC_LOGERR ("malloc nstack_fd_lock_info failed"); - return ns_fail; + get_default_base_cfg(1); + return 0; } - for (iindex = 0; iindex < (int) NSTACK_KERNEL_FD_MAX; iindex++) + mzone_handle base_cfg_mem = nsfw_mem_zone_lookup(&g_cfg_mem_info); + if (NULL == base_cfg_mem) { - fdInf = &g_nStackInfo.lk_sockPoll[iindex]; - nstack_reset_fdInf (fdInf); + NSSOC_LOGERR("get config share mem failed."); + return -1; } - if (-1 == nsep_init_infoSockMap ()) - { - NSSOC_LOGERR ("malloc epInfoPool fail"); - if (g_nStackInfo.lk_sockPoll) + if (get_share_cfg_from_mem(base_cfg_mem) < 0) { - free (g_nStackInfo.lk_sockPoll); - g_nStackInfo.lk_sockPoll = NULL; - } - return ns_fail; + NSSOC_LOGERR("get share config failed."); + return -1; } - return ns_success; + NSSOC_LOGDBG("get share config success."); + return 0; } - - /*design ensures that g_ksInfo is not write accessed at the same time. -only read is done simultaneously with no chance of other thread writing it. -so no protection needed.*/ -int -nstack_stack_init (void) -{ // Just need to create shared memory - int ret; + only read is done simultaneously with no chance of other thread writing it. + so no protection needed.*/ +int nstack_stack_init(void) +{ + // Just need to create shared memory + int ret; - ret = nstack_init_fd_local_info (); - if (ret != ns_success) + /* log add start. */ + ret = nstack_init_fd_local_info(); + if (ret != ns_success) { - goto INIT_DONE; + goto INIT_DONE; } - if (ns_fail == nstack_init_mem ()) + if (ns_fail == nstack_init_mem()) { - ret = ns_fail; - goto INIT_DONE; + ret = ns_fail; + goto INIT_DONE; } - if (SYS_HOST_INITIAL_PID == get_sys_pid ()) + if (SYS_HOST_INITIAL_PID == get_sys_pid()) { - ret = ns_fail; - goto INIT_DONE; + ret = ns_fail; + goto INIT_DONE; } - ret = ns_success; + ret = ns_success; + +#ifdef KERNEL_FD_SUPPORT + nsep_get_manager()->checkEpollFD = nsfw_base_epoll_create(1); +#endif -INIT_DONE: + INIT_DONE: - if (ns_success == ret) + if (ns_success == ret) { - NSSOC_LOGDBG ("success"); + NSSOC_LOGDBG("success"); } - else + else { - NSSOC_LOGERR ("fail"); + NSSOC_LOGERR("fail"); } - return ret; + return ret; } -int -nstack_for_epoll_init () +int nstack_for_epoll_init() { - NSSOC_LOGINF ("fork] init begin.."); - if (g_nStackInfo.pid != 0 && g_nStackInfo.pid != getpid ()) + NSSOC_LOGINF("fork] init begin.."); + if (g_nStackInfo.pid != 0 && g_nStackInfo.pid != getpid()) { - NSSOC_LOGINF ("fork]g_nStackInfo.pid=%u,getpid=%d", g_nStackInfo.pid, - getpid ()); + NSSOC_LOGINF("fork]g_nStackInfo.pid=%u,getpid=%d", g_nStackInfo.pid, + getpid()); - nstack_stack_module_init_child(); + nstack_register_module_forchild(); } - return 0; + return 0; } - - -void -signal_handler_app (int s) +void signal_handler_app(int s) { - NSPOL_LOGERR ("Received signal exiting.]s=%d", s); - if (SIGHUP != s && SIGTERM != s) + NSPOL_LOGERR("Received signal exiting.]s=%d", s); + if (SIGHUP != s && SIGTERM != s) { - nstack_segment_error (s); + nstack_segment_error(s); } } -void -register_signal_handler_app () +void register_signal_handler_app() { - /* handle function should comply secure coding standard - here mask signal that will use in sigwait() */ - sigset_t waitset, oset; - if (0 != sigemptyset (&waitset)) + /* signal handle function should comply secure coding standard + here mask signal that will use in sigwait() */ + sigset_t waitset, oset; + if (0 != sigemptyset(&waitset)) { - NSPOL_LOGERR ("sigemptyset failed"); + NSPOL_LOGERR("sigemptyset failed"); } - if (0 != sigaddset (&waitset, SIGRTMIN)) /* for timer */ + if (0 != sigaddset(&waitset, SIGRTMIN)) /* for timer */ { - NSPOL_LOGERR ("sigaddset failed"); + NSPOL_LOGERR("sigaddset failed"); } - if (0 != sigaddset (&waitset, SIGRTMIN + 2)) + if (0 != sigaddset(&waitset, SIGRTMIN + 2)) { - NSPOL_LOGERR ("sigaddset failed"); + NSPOL_LOGERR("sigaddset failed"); } - if (0 != pthread_sigmask (SIG_BLOCK, &waitset, &oset)) + if (0 != pthread_sigmask(SIG_BLOCK, &waitset, &oset)) { - NSPOL_LOGERR ("pthread_sigmask failed"); + NSPOL_LOGERR("pthread_sigmask failed"); } - - struct sigaction s; - s.sa_handler = signal_handler_app; - if (0 != sigemptyset (&s.sa_mask)) + struct sigaction s; + s.sa_handler = signal_handler_app; + if (0 != sigemptyset(&s.sa_mask)) { - NSPOL_LOGERR ("sigemptyset failed."); + NSPOL_LOGERR("sigemptyset failed."); } - s.sa_flags = (int) SA_RESETHAND; + s.sa_flags = (int) SA_RESETHAND; - /* register sig handler for more signals */ - if (sigaction (SIGINT, &s, NULL) != 0) + /*register sig handler for more signals [start] */ + if (sigaction(SIGINT, &s, NULL) != 0) { - NSPOL_LOGERR ("Could not register SIGINT signal handler."); + NSPOL_LOGERR("Could not register SIGINT signal handler."); } - if (sigaction (SIGSEGV, &s, NULL) != 0) + if (sigaction(SIGSEGV, &s, NULL) != 0) { - NSPOL_LOGERR ("Could not register SIGSEGV signal handler."); + NSPOL_LOGERR("Could not register SIGSEGV signal handler."); } - if (sigaction (SIGPIPE, &s, NULL) != 0) + if (sigaction(SIGPIPE, &s, NULL) != 0) { - NSPOL_LOGERR ("Could not register SIGPIPE signal handler."); + NSPOL_LOGERR("Could not register SIGPIPE signal handler."); } - if (sigaction (SIGFPE, &s, NULL) != 0) + if (sigaction(SIGFPE, &s, NULL) != 0) { - NSPOL_LOGERR ("Could not register SIGFPE signal handler."); + NSPOL_LOGERR("Could not register SIGFPE signal handler."); } - if (sigaction (SIGABRT, &s, NULL) != 0) + if (sigaction(SIGABRT, &s, NULL) != 0) { - NSPOL_LOGERR ("Could not register SIGABRT signal handler."); + NSPOL_LOGERR("Could not register SIGABRT signal handler."); } - if (sigaction (SIGBUS, &s, NULL) != 0) + if (sigaction(SIGBUS, &s, NULL) != 0) { - NSPOL_LOGERR ("Could not register SIGBUS signal handler."); + NSPOL_LOGERR("Could not register SIGBUS signal handler."); } - /* register sig handler for more signals */ - + /*register sig handler for more signals [end] */ } -int nstack_stack_module_load() +/*app send its version info to daemon-stack*/ +/* when an app init finish, register its version to daemon-stack, daemon-stack will record it */ +void nstack_app_touch(void) { - /*check whether already inited*/ - NSTACK_INIT_STATE_CHECK_RET(g_nStackInfo.moduleload); - - /*lock for fork*/ - common_mem_rwlock_read_lock(get_fork_lock()); - - if (pthread_mutex_lock(&g_nStackInfo.load_mutex)){ - NSSOC_LOGERR("nstack mutex lock fail"); - common_mem_rwlock_read_unlock(get_fork_lock()); - return -1; + int i; + for (i = 0; i < NSTACK_MAX_MODULE_NUM; i++) + { + if (nstack_fd_deal[i].app_touch) + { + nstack_fd_deal[i].app_touch(); + } } +} - NSTACK_INIT_STATE_CHECK_RET(g_nStackInfo.moduleload); - - NSTACK_THREAD_LOAD_SET(); - +int nstack_stack_module_load() +{ if (0 != nstack_module_parse()) { - NSSOC_LOGERR("nstack stack module parse fail"); + NSSOC_LOGERR("parse module config failed!"); goto LOAD_FAIL; } - if (0 != nstack_register_module()) { - NSSOC_LOGERR("nstack stack module parse fail"); + NSSOC_LOGERR("register modules failed, fallback to default one"); goto LOAD_FAIL; } - - NSTACK_THREAD_LOAD_UNSET(); - g_nStackInfo.moduleload = NSTACK_MODULE_SUCCESS; - common_mem_rwlock_read_unlock(get_fork_lock()); - pthread_mutex_unlock(&g_nStackInfo.load_mutex); return 0; -LOAD_FAIL: - g_nStackInfo.moduleload = NSTACK_MODULE_FAIL; - NSTACK_THREAD_LOAD_UNSET(); - common_mem_rwlock_read_unlock(get_fork_lock()); - pthread_mutex_unlock(&g_nStackInfo.load_mutex); + LOAD_FAIL: return -1; } -int -nstack_app_init (void *ppara) +int nstack_app_init(void *ppara) { - NSSOC_LOGINF("nstack app init begin"); + NSSOC_LOGINF("nstack app init begin"); + + if (get_share_config() < 0) + { + NSSOC_LOGERR("get share config failed"); + return ns_fail; + } + + if (g_nStackInfo.pid != 0 && g_nStackInfo.pid != getpid()) + { + NSSOC_LOGINF("fork]g_nStackInfo.pid=%u,getpid=%d", g_nStackInfo.pid, + getpid()); + nstack_register_module_forchild(); + } +#ifdef KERNEL_FD_SUPPORT + long sysfdmax = 0; + sysfdmax = sysconf(_SC_OPEN_MAX); + NSSOC_LOGINF("sys max open files:%ld", sysfdmax); + if (sysfdmax > 0) + { + g_nStackInfo.ikernelfdmax = + (uint32_t) ((sysfdmax <= + ((NSTACK_MAX_SOCK_NUM / 8) * + 60)) ? sysfdmax : ((NSTACK_MAX_SOCK_NUM / 8) * 60)); + } + else + { + NSSOC_LOGERR("get sys max open file fail"); + g_nStackInfo.ikernelfdmax = NSTACK_MAX_SOCK_NUM; + } +#endif + NSSOC_LOGINF("final max fd:%u", g_nStackInfo.ikernelfdmax); - g_nStackInfo.ikernelfdmax = nstack_get_maxfd_id(nstack_get_fix_mid()); + nstack_set_maxfd_id(nstack_get_linux_mid(), g_nStackInfo.ikernelfdmax); - NSSOC_LOGINF("final max fd:%d", g_nStackInfo.ikernelfdmax); + g_nStackInfo.pid = getpid(); - g_nStackInfo.pid = getpid (); + /*if init already, just return success, if init fail before, just return err */ + if (NSTACK_MODULE_INIT != g_nStackInfo.hasInited) + { + NSSOC_LOGINF("nstack app already init state:%d", + g_nStackInfo.hasInited); + return (NSTACK_MODULE_SUCCESS == + g_nStackInfo.hasInited ? ns_success : ns_fail); + } - /*if init already, just return success, if init fail before, just return err */ - if (NSTACK_MODULE_INIT != g_nStackInfo.hasInited) + if (0 != nstack_stack_init()) { - NSSOC_LOGINF ("nstack app already init state:%d", - g_nStackInfo.hasInited); - return (NSTACK_MODULE_SUCCESS == - g_nStackInfo.hasInited ? ns_success : ns_fail); + NSSOC_LOGERR("nstack stack init failed"); + g_nStackInfo.hasInited = NSTACK_MODULE_FAIL; + return ns_fail; } - if (0 != nstack_stack_init ()) + nstack_app_touch(); /*app send its version info to daemon-stack */ + + g_nStackInfo.hasInited = NSTACK_MODULE_SUCCESS; + NSSOC_LOGINF("nstack app init success end"); + return ns_success; +} + +int mem_adpt_init(void *handle, nsfw_mem_attr * mem_ops, + nsfw_ring_ops * ring_ops) +{ + int i = 0; + nsfw_ring_ops *temp_ring_ops; + + mem_ops[NSFW_SHMEM].stmemop = dlsym(handle, "g_shmem_ops"); + mem_ops[NSFW_NSHMEM].stmemop = dlsym(handle, "g_nshmem_ops"); + temp_ring_ops = dlsym(handle, "g_ring_ops_arry_spl"); + + for (i = 0; i < NSFW_MEM_TYPEMAX * NSFW_MPOOL_TYPEMAX; i++) { - NSSOC_LOGERR ("nstack stack init failed"); - g_nStackInfo.hasInited = NSTACK_MODULE_FAIL; - return ns_fail; + ring_ops[i] = *temp_ring_ops; + temp_ring_ops++; } - g_nStackInfo.hasInited = NSTACK_MODULE_SUCCESS; - NSSOC_LOGINF ("nstack app init success end"); - return ns_success; + NSFW_LOGINF("get shmem and nshmem and ring_ops ops var success."); + + return 0; } /*nsocket call framework init fun*/ -int -nstack_fw_init () +int nstack_fw_init() +{ + int ret = ns_fail; + + if (NSTACK_MODULE_SUCCESS == g_nStackInfo.fwInited) + { + return ns_success; + } + if (NSTACK_MODULE_INIT == g_nStackInfo.fwInited) + { + g_nStackInfo.fwInited = NSTACK_MODULE_INITING; + nstack_log_init_app(); + if (0 != nstack_stack_module_load()) + { + NSSOC_LOGERR("nstack stack module load failed!"); + g_nStackInfo.fwInited = NSTACK_MODULE_FAIL; + return -1; + } + + dmm_read_lock(get_fork_lock()); + updata_sys_pid(); + u8 proc_type = NSFW_PROC_APP; + nsfw_mem_para stinfo = { 0 }; + stinfo.iargsnum = 0; + stinfo.pargs = NULL; + stinfo.enflag = (fw_poc_type) proc_type; + + nstack_framework_set_module_param(NSFW_MEM_MGR_MODULE, + (void *) &stinfo); + nstack_framework_set_module_param(NSFW_MGR_COM_MODULE, + (void *) ((long long) proc_type)); + nstack_framework_set_module_param(NSFW_PS_MODULE, + (void *) ((long long) proc_type)); + nstack_framework_set_module_param(NSFW_PS_MEM_MODULE, + (void *) ((long long) proc_type)); + nstack_framework_set_module_param(NSFW_RECYCLE_MODULE, + (void *) ((long long) proc_type)); + + ret = nstack_framework_init(); + + if (ns_success == ret) + { + g_nStackInfo.fwInited = NSTACK_MODULE_SUCCESS; + } + else + { + g_nStackInfo.fwInited = NSTACK_MODULE_FAIL; + } + dmm_read_unlock(get_fork_lock()); + } + return ret; +} + +nstack_fd_local_lock_info_t *get_fd_local_lock_info(int fd) { + if (!g_nStackInfo.lk_sockPool) + { + return NULL; + } + + if (fd >= 0 && fd < (int) NSTACK_KERNEL_FD_MAX) + { + return &(g_nStackInfo.lk_sockPool[fd].local_lock); + } - int ret = ns_fail; - - if (NSTACK_MODULE_SUCCESS == g_nStackInfo.fwInited) - { - return ns_success; - } - - if (NSTACK_MODULE_INIT == g_nStackInfo.fwInited) - { - g_nStackInfo.fwInited = NSTACK_MODULE_INITING; - nstack_log_init_app(); - - if (0 != nstack_stack_module_load()) - { - NSSOC_LOGERR("nstack stack module load fail"); - g_nStackInfo.fwInited = NSTACK_MODULE_FAIL; - return -1; - } - - common_mem_rwlock_read_lock (get_fork_lock ()); - update_sys_pid (); - u8 proc_type = NSFW_PROC_APP; - nsfw_mem_para stinfo = { 0 }; - - int deploytype = nstack_get_deploy_type(); - - if (deploytype == NSTACK_MODEL_TYPE1) - { - proc_type = NSFW_PROC_MAIN; - }else if (deploytype == NSTACK_MODEL_TYPE_SIMPLE_STACK) - { - proc_type = NSFW_PROC_MAIN; - app_mode=1; - } - - stinfo.iargsnum = 0; - stinfo.pargs = NULL; - stinfo.enflag = (fw_poc_type)proc_type; - nstack_framework_setModuleParam(NSFW_MEM_MGR_MODULE, (void*)&stinfo); - nstack_framework_setModuleParam(NSFW_MGR_COM_MODULE, (void*) ((long long)proc_type)); - nstack_framework_setModuleParam(NSFW_TIMER_MODULE, (void*) ((long long)proc_type)); - nstack_framework_setModuleParam(NSFW_PS_MODULE, (void*) ((long long)proc_type)); - nstack_framework_setModuleParam(NSFW_PS_MEM_MODULE, (void*) ((long long)proc_type)); - nstack_framework_setModuleParam(NSFW_RECYCLE_MODULE, (void*) ((long long)proc_type)); - NSTACK_THREAD_LOAD_SET(); - ret = nstack_framework_init(); - - if (ns_success == ret) - { - g_nStackInfo.fwInited = NSTACK_MODULE_SUCCESS; - } - else - { - g_nStackInfo.fwInited = NSTACK_MODULE_FAIL; - } - NSTACK_THREAD_LOAD_UNSET(); - common_mem_rwlock_read_unlock(get_fork_lock()); - } - - return ret; + return NULL; } -nstack_fd_local_lock_info_t * -get_fd_local_lock_info (int fd) +int nstack_dmm_dfx_init(nstack_proc_ops * ops) { - if (!g_nStackInfo.lk_sockPoll) + int i; + int ret; + nstack_dmm_stack_ops_t dfx_ops[NSTACK_MAX_MODULE_NUM]; + + if (!ops) + return ns_fail; + + dmm_fd_dfx_pool = (nstack_fd_dfx_t *) malloc(NSTACK_KERNEL_FD_MAX * sizeof(nstack_fd_dfx_t)); /*malloc can be used */ + if (!dmm_fd_dfx_pool) + { + NSSOC_LOGERR("malloc fd_dfx_pool failed"); + free(g_nStackInfo.lk_sockPool); + g_nStackInfo.lk_sockPool = NULL; + return ns_fail; + + } + else { - return NULL; + ret = + memset_s(dmm_fd_dfx_pool, + NSTACK_KERNEL_FD_MAX * sizeof(nstack_fd_dfx_t), 0, + NSTACK_KERNEL_FD_MAX * sizeof(nstack_fd_dfx_t)); + if (EOK != ret) + { + NSSOC_LOGERR("memset failed"); + free(g_nStackInfo.lk_sockPool); + g_nStackInfo.lk_sockPool = NULL; + free(dmm_fd_dfx_pool); + dmm_fd_dfx_pool = NULL; + return ns_fail; + } } - if (fd >= 0 && fd < (int) NSTACK_KERNEL_FD_MAX) + for (i = 0; i < NSTACK_MAX_MODULE_NUM; i++) { - return &(g_nStackInfo.lk_sockPoll[fd].local_lock); + dfx_ops[i].get_stack_tick = ops[i].get_stack_tick; + dfx_ops[i].update_dfx_data = ops[i].update_dfx_data; + dfx_ops[i].type = 0; } - return NULL; + return nstack_dfx_init_ops(dfx_ops); } diff --git a/src/nSocket/nstack/nstack.h b/src/nSocket/nstack/nstack.h index 1ec88f0..d167899 100644 --- a/src/nSocket/nstack/nstack.h +++ b/src/nSocket/nstack/nstack.h @@ -28,9 +28,8 @@ #include "nstack_module.h" #include "nstack_fd_mng.h" -#include "nstack_types.h" +#include "types.h" #include "nstack_eventpoll.h" -#include "common_mem_api.h" #include "nstack_select.h" #include <stdio.h> @@ -38,11 +37,9 @@ #include <string.h> #include <unistd.h> #include "nstack_atomic.h" -#include "common_mem_spinlock.h" -#include "generic/common_mem_rwlock.h" - #include "nsfw_mem_api.h" #include "nsfw_recycle_api.h" +#include "dmm_rwlock.h" #ifdef __cplusplus /* *INDENT-OFF* */ @@ -52,32 +49,53 @@ extern "C"{ #define NSTACK_PIDINFO "hw_nstack_pidinfo" +typedef struct _dict_ +{ + int n; + ssize_t size; + char **key; + char **val; + unsigned *hash; +} dict; +/* release sockets when app exit */ +typedef struct +{ + uint32_t hostpid; + uint32_t pid; + uint64_t pidns; + atomic_t socketCount; +} __attribute__ ((__packed__)) nStackPidInfo_t; + typedef enum { - NSTACK_MODULE_INIT, - NSTACK_MODULE_INITING, - NSTACK_MODULE_SUCCESS, - NSTACK_MODULE_FAIL + NSTACK_MODULE_INIT, + NSTACK_MODULE_INITING, + NSTACK_MODULE_SUCCESS, + NSTACK_MODULE_FAIL } nstack_module_state; typedef struct { - nstack_module_state hasInited; /*nsocket inside init status */ - nstack_module_state fwInited; /*framework init status */ - nstack_module_state moduleload; /*framework init status */ - char pad1[2]; - - pthread_mutex_t load_mutex; - /* if a nstack_fd_Inf contains a valid linux kernel proFD, it will be allocated from this poll. - * Total size of the poll is NSTACK_MAX_SOCK_NUM, index range is [0, NSTACK_MAX_SOCK_NUM). - */ - nstack_fd_Inf *lk_sockPoll; - - common_mem_rwlock_t fork_lock; /* to ensure that there is no fd to create and close when fork */ - uint32_t pid; - char *nstack_version; - int checkEpollFD; - uint32_t ikernelfdmax; + nstack_module_state hasInited; /*nsocket inside init status */ + nstack_module_state fwInited; /*framework init status */ + char pad1[2]; + + pthread_mutex_t init_mutex; + /* if a nstack_fd_Inf contains a valid linux kernel proFD, it will be allocated from this poll. + * Total size of the poll is NSTACK_MAX_SOCK_NUM, index range is [0, NSTACK_MAX_SOCK_NUM). + */ + nstack_fd_Inf *lk_sockPool; + +#ifndef KERNEL_FD_SUPPORT + int fdhead; + dmm_spinlock_t fdlock; +#endif + + dmm_rwlock_t fork_lock; /* to ensure that there is no fd to create and close when fork. */ + uint32_t pid; + char *nstack_version; + int checkEpollFD; + uint32_t ikernelfdmax; } __attribute__ ((__packed__)) nStack_info_t; #define ENV_NSTACK_RD_CFG_PATH "NSTACK_RD_CFG_PATH" @@ -85,33 +103,25 @@ typedef struct #define nstack_set_errno(no) errno = (no) extern nStack_info_t g_nStackInfo; -extern __thread int g_tloadflag; #define NSTACK_KERNEL_FD_MAX (g_nStackInfo.ikernelfdmax) -#define NSTACK_THREAD_LOAD_SET() (g_tloadflag = 1) -#define NSTACK_THREAD_LOAD_UNSET() (g_tloadflag = 0) -#define NSTACK_THREAD_LOADING() (g_tloadflag == 1) #define nstack_each_protoFDSt(modInx, fdInf, st) \ - for ((modInx) = 0; ((modInx) < nstack_get_modNum() && ((st) = nstack_get_protoFdSt((fdInf), modInx))); (modInx)++) - -extern int nstack_timeval2msec (struct timeval *pTime, u64_t * msec); -extern int nstack_current_time2msec (u64_t * msec); -extern int nstack_sem_timedwait (sem_t * pSem, u64_t abs_timeout /*ms */ ); -extern int nstack_epoll_sem_timedwait (sem_t * pSem, - u64_t abs_timeout /*ms */ , - long wait_time /*us */ ); -extern int nstack_app_init (void *ppara); -extern int nstack_fw_init (); - -nstack_fd_local_lock_info_t *get_fd_local_lock_info (int fd); -void nstack_fork_fd_local_lock_info (nstack_fd_local_lock_info_t * + for ((modInx) = 0; ((modInx) < nstack_get_module_num() && ((st) = nstack_get_proto_fd_st((fdInf), modInx))); (modInx)++) + +extern int nstack_timeval2msec(struct timeval *pTime, long *msec); +extern int nstack_current_time2msec(long *msec); +extern int nstack_sem_timedwait(sem_t * pSem, long abs_timeout /*ms */ , + long *mcost); +extern int nstack_app_init(void *ppara); +extern int nstack_fw_init(); + +nstack_fd_local_lock_info_t *get_fd_local_lock_info(int fd); +void nstack_fork_fd_local_lock_info(nstack_fd_local_lock_info_t * local_lock); +void nstack_reset_fd_local_lock_info(nstack_fd_local_lock_info_t * local_lock); -void nstack_reset_fd_local_lock_info (nstack_fd_local_lock_info_t * - local_lock); -common_mem_rwlock_t *get_fork_lock (); -int nstack_for_epoll_init (); -int nstack_stack_module_load (); +dmm_rwlock_t *get_fork_lock(); +int nstack_for_epoll_init(); #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/nSocket/nstack/nstack_fd_mng.c b/src/nSocket/nstack/nstack_fd_mng.c index 86e045d..81d3818 100644 --- a/src/nSocket/nstack/nstack_fd_mng.c +++ b/src/nSocket/nstack/nstack_fd_mng.c @@ -25,216 +25,340 @@ #include "nstack_fd_mng.h" #include "nstack_socket.h" #include "nstack_securec.h" -#include "nstack_sockops.h" +#include "nsfw_base_linux_api.h" +#include "nstack_dmm_dfx.h" + +static inline void nstack_reset_fd_dfx(int fd) +{ + if (dmm_fd_dfx_pool && fd >= 0 && (u32_t) fd < NSTACK_KERNEL_FD_MAX) + { + if (memset_s + (&dmm_fd_dfx_pool[fd], sizeof(nstack_fd_dfx_t), 0, + sizeof(nstack_fd_dfx_t))) + { + NSSOC_LOGERR("memset failed"); + } + } + return; +} /* test_epollCtl_004_001_trial : both 32bit and 64bit members of 'ops' and 'conn' need to reset, otherwise it will be invalid address in 32bit APP case */ -void -nstack_reset_fdInf (nstack_fd_Inf * fdInf) +/*no need to check null pointer here*/ +void nstack_reset_fd_inf(nstack_fd_Inf * fdInf) { - int loop; - - fdInf->isBound = NSTACK_FD_NOBIND; - fdInf->rlfd = -1; - fdInf->rmidx = -1; - fdInf->nxtfd = -1; - fdInf->fd = -1; - fdInf->attr = 0; - fdInf->ops = 0; /*operations of the fd, for save space we user opIdx here */ - fdInf->type = 0; /*the fd type like SOCK_STREAM|SOCK_NONBLOCK ... */ + int loop; + fdInf->isBound = NSTACK_FD_NOBIND; + fdInf->rlfd = -1; + fdInf->rmidx = -1; +#ifdef KERNEL_FD_SUPPORT + fdInf->nxtfd = -1; + fdInf->fd = -1; +#else + fdInf->stat = NSTACK_FD_DISCARD; +#endif + fdInf->attr = 0; + fdInf->ops = 0; /*opers of the fd, for save space we user opIdx here */ + fdInf->type = 0; /*the fd type like SOCK_STREAM|SOCK_NONBLOCK ... */ - NSTACK_SET_FD_BLOCKING (fdInf); - for (loop = 0; loop < NSTACK_MAX_MODULE_NUM; loop++) + NSTACK_SET_FD_BLOKING(fdInf); + for (loop = 0; loop < NSTACK_MAX_MODULE_NUM; loop++) { - fdInf->protoFD[loop].fd = -1; - fdInf->protoFD[loop].errCode = 0; - fdInf->protoFD[loop].pad = 0; - fdInf->protoFD[loop].liststate = NSTACK_NO_LISTENING; + fdInf->protoFD[loop].fd = -1; + fdInf->protoFD[loop].errCode = 0; + fdInf->protoFD[loop].pad = 0; + fdInf->protoFD[loop].liststate = NSTACK_NO_LISENING; } - nstack_reset_fd_local_lock_info (&(fdInf->local_lock)); - return; + nstack_reset_fd_local_lock_info(&(fdInf->local_lock)); + return; } -nstack_fd_Inf * -nstack_fd2inf (int fd) +nstack_fd_Inf *nstack_fd2inf(int fd) { - /*if nstack init not finished, just return null */ - if (NSTACK_MODULE_SUCCESS != g_nStackInfo.fwInited) + /*if nstack init not finished, just return null */ + if (NSTACK_MODULE_SUCCESS != g_nStackInfo.fwInited) { - return NULL; + return NULL; } - if (nstack_is_nstack_sk (fd) && g_nStackInfo.lk_sockPoll) + if (nstack_is_nstack_sk(fd) && g_nStackInfo.lk_sockPool) { - return &(g_nStackInfo.lk_sockPoll[fd]); + return &(g_nStackInfo.lk_sockPool[fd]); } - return NULL; + return NULL; } -void -nstack_set_protoFd (nstack_fd_Inf * fdInf, int modInx, int protofd) +/*no need to check null pointer here*/ +void nstack_set_proto_fd(nstack_fd_Inf * fdInf, int modInx, int protofd) { - if (protofd < nstack_get_minfd_id (modInx) - || protofd > nstack_get_maxfd_id (modInx)) + if (protofd < nstack_get_minfd_id(modInx) + || protofd > nstack_get_maxfd_id(modInx)) { - NSSOC_LOGERR ("module:%d protofd invalid] protofd=%d", modInx, protofd); - return; + NSSOC_LOGDBG("module:%d protofd invalid] protofd=%d", modInx, + protofd); + return; } - nstack_get_protoFd (fdInf, modInx) = protofd; + nstack_get_proto_fd(fdInf, modInx) = protofd; - nsep_set_infoProtoFD (fdInf->fd, modInx, protofd); + nsep_set_info_proto_fd(fdInf->fd, modInx, protofd); - nssct_create (fdInf->fd, protofd, modInx); - return; + nssct_create(fdInf->fd, protofd, modInx); /*do not need return value */ + return; } /* pass app info to struct netconn */ -void -nstack_set_app_info (nstack_fd_Inf * fdInf, int modInx) +void nstack_set_app_info(nstack_fd_Inf * fdInf, int modInx) { - return; + if (nstack_fd_deal[modInx].set_app_info) + { + struct nsfw_app_info appinfo; + + appinfo.hostpid = get_sys_pid(); + appinfo.pid = getpid(); + appinfo.ppid = getppid(); + appinfo.tid = (int) syscall(SYS_gettid); + appinfo.nsocket_fd = fdInf->fd; + appinfo.sbr_fd = nstack_get_proto_fd(fdInf, modInx); + + nstack_fd_deal[modInx].set_app_info(appinfo.sbr_fd, + (void *) &appinfo); + } + + return; } -nstack_fd_Inf * -nstack_lk_fd_alloc_with_kernel (int nfd) +#ifdef KERNEL_FD_SUPPORT + +/* release sockets when app exit */ +nstack_fd_Inf *nstack_lk_fd_alloc_with_kernel(int nfd) { - nstack_fd_Inf *retInf = NULL; + nstack_fd_Inf *retInf = NULL; - if ((nfd < 0) || (nfd >= (int) NSTACK_KERNEL_FD_MAX) - || (!g_nStackInfo.lk_sockPoll)) + if ((nfd < 0) || (nfd >= (int) NSTACK_KERNEL_FD_MAX) + || (!g_nStackInfo.lk_sockPool)) { - NSSOC_LOGERR - ("nfd < 0 or nfd>= NSTACK_KERNEL_FD_MAX, parameter not valid"); - return NULL; + NSSOC_LOGERR + ("nfd < 0 or nfd>= NSTACK_KERNEL_FD_MAX, parameter not valid"); + return NULL; } - retInf = &g_nStackInfo.lk_sockPoll[nfd]; + retInf = &g_nStackInfo.lk_sockPool[nfd]; - if (FD_OPEN == retInf->local_lock.fd_status) + if (FD_OPEN == retInf->local_lock.fd_status) { - NSSOC_LOGERR ("nstack_lk_fd_alloc_with_kernel fd:%d already create", - nfd); + NSSOC_LOGERR("nstack_lk_fd_alloc_with_kernel fd:%d already create", + nfd); } - retInf->fd = nfd; - if (-1 == nsep_alloc_infoWithSock (nfd)) + retInf->fd = nfd; + if (-1 == nsep_alloc_info_with_sock(nfd)) { - NSSOC_LOGERR ("Can't alloc epInfo for nfd=%d]", nfd); - nstack_reset_fdInf (retInf); - return NULL; + NSSOC_LOGERR("Can't alloc epInfo for nfd=%d]", nfd); + nstack_reset_fd_inf(retInf); + nstack_reset_fd_dfx(nfd); + return NULL; } - nstack_set_protoFd (retInf, g_nstack_modules.fix_mid, nfd); - NSSOC_LOGDBG ("nfd=%d,retInf_fd=%d", nfd, retInf->fd); - return retInf; + nstack_set_proto_fd(retInf, nstack_get_linux_mid(), nfd); + NSSOC_LOGDBG("nfd=%d,retInf_fd=%d", nfd, retInf->fd); + return retInf; } - -int -nstack_fd_free_with_kernel (nstack_fd_Inf * fdInf) +#else +nstack_fd_Inf *nstack_fd_alloc(void) { - int closeRet = 0; - ns_int32 fd; - - if (!fdInf) + int tfd; + int LoopCount = 0; + if (!g_nStackInfo.lk_sockPool) { - NSSOC_LOGERR ("fdInf is NULL"); - return 0; + return NULL; } - fd = fdInf->protoFD[nstack_get_fix_mid ()].fd; - nstack_reset_fdInf (fdInf); - if (fd >= 0 && fd < (int) NSTACK_KERNEL_FD_MAX) + /*begin using SpinLock instead CAS, to avoid ABA problem */ + dmm_spin_lock_with_pid((dmm_spinlock_t *) & g_nStackInfo.fdlock); + /* [Add memory alloc state] */ + do { - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (fd), closeRet); - NSSOC_LOGINF ("close]fd=%d,ret=%d", fd, closeRet); + /* loop count should not be more than NSTACK_MAX_NON_LK_SOCK_NUM */ + if (LoopCount > NSTACK_MAX_SOCK_NUM) + { + dmm_spin_unlock((dmm_spinlock_t *) (&g_nStackInfo.fdlock)); + NSSOC_LOGERR("some err happen in alloc one fdInf"); + return NULL; + } + + /* add tfd rang check */ + if (0 > (tfd = g_nStackInfo.fdhead) || tfd >= NSTACK_MAX_SOCK_NUM) + { + dmm_spin_unlock((dmm_spinlock_t *) (&g_nStackInfo.fdlock)); + NSSOC_LOGERR("fdinfo was empty"); + return NULL; + } + g_nStackInfo.fdhead = g_nStackInfo.lk_sockPool[tfd].nxtfd; + if (NSTACK_FD_DISCARD == g_nStackInfo.lk_sockPool[tfd].stat) + { + g_nStackInfo.lk_sockPool[tfd].stat = NSTACK_FD_INUSING; + break; + } + else + { + NSSOC_LOGWAR("Alloc one fdInf with stat %d [not correct]", + g_nStackInfo.lk_sockPool[tfd].stat); + + } + LoopCount++; } - return closeRet; + while (1); + /* [Add memory alloc state] */ + dmm_spin_unlock((dmm_spinlock_t *) (&g_nStackInfo.fdlock)); + /*end using SpinLock instead CAS, to avoid ABA problem */ + + return &g_nStackInfo.lk_sockPool[tfd]; } -void -nstack_fork_init_parent (pid_t ppid) +void nstack_fd_free(nstack_fd_Inf * fdInf) { - int fd; - nstack_fd_Inf *fdInf = NULL; - for (fd = 0; fd < (int) NSTACK_KERNEL_FD_MAX; fd++) + int nfd; + + nfd = fdInf->fd; + + if (nfd < NSTACK_MAX_SOCK_NUM && nfd > -1) { - fdInf = nstack_getValidInf (fd); - if ((NULL != fdInf) && (!((u32_t) (fdInf->type) & SOCK_CLOEXEC))) + dmm_spin_lock_with_pid((dmm_spinlock_t *) & g_nStackInfo.fdlock); + if (NSTACK_FD_INUSING != fdInf->stat) { - int i; - nstack_each_modInx (i) - { - if ((nstack_extern_deal (i).fork_parent_fd) - && (fdInf->protoFD[i].fd >= 0)) - { - nstack_extern_deal (i).fork_parent_fd (fdInf->protoFD[i].fd, - ppid); - } - } + NSSOC_LOGERR("fdInf not alloced yet!"); + dmm_spin_unlock((dmm_spinlock_t *) (&g_nStackInfo.fdlock)); + return; } + nstack_reset_fd_inf(fdInf); + nstack_reset_fd_dfx(nfd); + g_nStackInfo.lk_sockPool[nfd].nxtfd = g_nStackInfo.fdhead; + g_nStackInfo.fdhead = nfd; + dmm_spin_unlock((dmm_spinlock_t *) (&g_nStackInfo.fdlock)); } + return; } -void -nstack_fork_init_child (pid_t ppid) +nstack_fd_Inf *nstack_lk_fd_alloc_without_kernel() { - pid_t cpid = update_sys_pid (); - NSSOC_LOGDBG ("parent_pid=%d, child_pid=%d", ppid, cpid); + nstack_fd_Inf *retInf = NULL; + + retInf = nstack_fd_alloc(); + if (!retInf) + { + NSSOC_LOGERR("nstack_lk_fd_alloc_without_kernel fail"); + return NULL; + } + + if (FD_OPEN == retInf->local_lock.fd_status) + { + NSSOC_LOGWAR + ("nstack_lk_fd_alloc_without_kernel fd:%d already create", + retInf->fd); - nsfw_mgr_clr_fd_lock (); - if (FALSE == nsfw_recycle_fork_init ()) + } + + if (-1 == nsep_alloc_info_with_sock(retInf->fd)) { - NSFW_LOGERR ("init rec zone failed!]ppid=%d,cpid=%d", ppid, cpid); + NSSOC_LOGERR("Can't alloc epInfo for nfd=%d]", retInf->fd); + nstack_reset_fd_inf(retInf); + nstack_reset_fd_dfx(retInf->fd); + return NULL; } - int i; - nstack_each_modInx (i) - { - if (nstack_extern_deal (i).fork_init_child) - { - nstack_extern_deal (i).fork_init_child (ppid, cpid); - } - } + NSSOC_LOGDBG("retInf->fd=%d", retInf->fd); + return retInf; +} +#endif + +/* should release resource for kernel */ +static int nstack_close_kernel_socket(int fd) +{ + return nsfw_base_close(fd); +} + +int nstack_fd_free_with_kernel(nstack_fd_Inf * fdInf) +{ + int closeRet = 0; + ns_int32 fd; + + if (!fdInf) + { + NSSOC_LOGERR("fdInf is NULL"); + return 0; + } + fd = fdInf->protoFD[nstack_get_linux_mid()].fd; + nstack_reset_fd_dfx(fd); + nstack_reset_fd_inf(fdInf); - int pos; - nstack_fd_Inf *fdInf = NULL; + if (fd >= 0 && fd < (int) NSTACK_KERNEL_FD_MAX) + { + closeRet = nstack_close_kernel_socket(fd); + NSSOC_LOGINF("close]fd=%d,ret=%d", fd, closeRet); + } + return closeRet; +} - for (pos = 0; pos < (int) NSTACK_KERNEL_FD_MAX; pos++) +void nstack_fork_fd(pid_t ppid) +{ + int i; + int fd; + nstack_fd_Inf *fdInf = NULL; + pid_t cpid = get_sys_pid(); + for (fd = 0; fd < (int) NSTACK_KERNEL_FD_MAX; fd++) { - fdInf = nstack_getValidInf (pos); - if (fdInf) + fdInf = nstack_get_valid_inf(fd); + if (fdInf) { - if (!((u32_t) (fdInf->type) & SOCK_CLOEXEC)) + if (!((u32_t) (fdInf->type) & SOCK_CLOEXEC)) { - nstack_fork_fd_local_lock_info (&fdInf->local_lock); - - nstack_each_modInx (i) - { - if ((nstack_extern_deal (i).fork_child_fd) - && (fdInf->protoFD[i].fd >= 0)) - { - nstack_extern_deal (i).fork_child_fd (fdInf-> - protoFD[i].fd, ppid, - cpid); - } - } + nstack_fork_fd_local_lock_info(&fdInf->local_lock); + nstack_each_mod_inx(i) + { + if ((nstack_fd_deal[i].fork_fd) + && (fdInf->protoFD[i].fd >= 0)) + { + nstack_fd_deal[i].fork_fd(fdInf->protoFD[i].fd, ppid, + cpid); + } + } } - else + else { - nstack_reset_fd_local_lock_info (&fdInf->local_lock); - nsep_set_infoSockMap (pos, NULL); - nstack_each_modInx (i) - { - if ((nstack_extern_deal (i).fork_free_fd) - && (fdInf->protoFD[i].fd >= 0)) - { - nstack_extern_deal (i).fork_free_fd (fdInf->protoFD[i].fd, - ppid, cpid); - } - } + nstack_reset_fd_local_lock_info(&fdInf->local_lock); + nsep_set_info_sock_map(fd, NULL); + nstack_each_mod_inx(i) + { + if ((nstack_fd_deal[i].fork_free_fd) + && (fdInf->protoFD[i].fd >= 0)) + { + nstack_fd_deal[i].fork_free_fd(fdInf->protoFD[i].fd); + } + } } } } } + +void nstack_fork_init_child(pid_t ppid) +{ + pid_t cpid = updata_sys_pid(); + NSSOC_LOGDBG("parent_pid=%d, child_pid=%d", ppid, cpid); + + nsfw_mgr_clr_fd_lock(); + if (FALSE == nsfw_recycle_fork_init()) + { + NSFW_LOGERR("init rec zone failed!]ppid=%d,cpid=%d", ppid, cpid); + } + + int i; + nstack_each_mod_inx(i) + { + if (nstack_fd_deal[i].fork_init_child) + { + nstack_fd_deal[i].fork_init_child(ppid, cpid); + } + } +} diff --git a/src/nSocket/nstack/nstack_fd_mng.h b/src/nSocket/nstack/nstack_fd_mng.h index cb25e8e..fcf7ed4 100644 --- a/src/nSocket/nstack/nstack_fd_mng.h +++ b/src/nSocket/nstack/nstack_fd_mng.h @@ -18,15 +18,17 @@ #define __NSTACK_FD_MNG_H__ #include <semaphore.h> +#ifndef SPL_INSTANCE_H #include "nstack_atomic.h" +#endif #include "types.h" #include "nstack_module.h" -#include "nstack_types.h" -#include "nstack_eventpoll.h" -#include "common_mem_spinlock.h" -#include "common_mem_api.h" -#include "common_func.h" + +#include "pid_common.h" +#include "nsfw_maintain_api.h" +#include "dmm_spinlock.h" +#include "nstack_rd_priv.h" #ifdef __cplusplus /* *INDENT-OFF* */ @@ -34,12 +36,14 @@ extern "C" { /* *INDENT-ON* */ #endif +#define KERNEL_FD_SUPPORT 1 + #define NSTACK_FDT_BLOCK_NOFFSET 10 #define NSTACK_FDT_CONVERT_FLAG 0x40000000 /* flag set means nstack socket */ -#define NSTACK_MAX_SOCK_NUM 8192 +#define NSTACK_MAX_SOCK_NUM MAX_SOCKET_NUM -#define NSTACK_MAX_PID 65536 /* release sockets when app exit */ +#define NSTACK_MAX_PID 65536 /* release sockets when app exit Add */ #ifndef AF_INET #define AF_INET 2 @@ -50,28 +54,37 @@ extern "C" { /* setsockopt level type*/ enum { - NSTACK_SOCKOPT = 0xff02 + NSTACK_SOCKOPT = 0xff02 }; /*setsockopt optname type*/ enum { - NSTACK_SEM_SLEEP = 0X001 + NSTACK_SEM_SLEEP = 0X001, + MPTCP_SET_PRIO = 0X002, + NSTACK_RD_MODE = 0X003, +}; + +enum +{ + NSTACK_RD_OPT_KERNEL = 0, + NSTACK_RD_OPT_STACKPOOL = 1, + NSTACK_RD_OPT_MAX = 2, }; #endif #define nstack_is_nstack_sk(fd) ((fd) >= 0 && ((fd) < (int)NSTACK_KERNEL_FD_MAX)) typedef enum __nstack_fd_Stat { - NSTACK_FD_INUSING, - NSTACK_FD_DISCARD + NSTACK_FD_INUSING, + NSTACK_FD_DISCARD } nstack_fd_stat; #define NSTACK_BIND_SUCCESS 0 #define NSTACK_LISTEN_SUCCESS 0 #define NSTACK_LISTEN_FAIL 1 #define NSTACK_BIND_FAIL 1 -#define NSTACK_LISTENING 1 -#define NSTACK_NO_LISTENING 0 +#define NSTACK_LISENING 1 +#define NSTACK_NO_LISENING 0 #define NSTACK_FD_INIT (0) #define NSTACK_FD_OPEN (1) @@ -80,81 +93,94 @@ typedef enum __nstack_fd_Stat #define NSTACK_FD_NOBIND (0) #define NSTACK_FD_BIND (1) -/* release sockets when app exit */ - typedef struct { - ns_int32 fd; - ns_int32 errCode; - union - { - struct result + ns_int32 fd; + ns_int32 errCode; + union { - ns_int32 brslt:8; - ns_int32 lrslt:8; - ns_int32 resrv:16; - } rslt; - ns_int32 pad; - }; - ns_int32 liststate; + struct reslt + { + ns_int32 brslt:8; + ns_int32 lrslt:8; + ns_int32 resrv:16; + } rslt; + ns_int32 pad; + }; + ns_int32 liststate; } __attribute__ ((__packed__)) nstack_protoFD_t; -#define NSTACK_FD_ATTR_NONBLOCKING 0x00000001 +#define NSTACK_FD_ATTR_NONBLOKING 0x00000001 #define NSTACK_FD_ATTR_EPOLL_SOCKET 0x00000002 #define NSTACK_FD_ATTR_LISTEN_SOCKET 0x00000004 -#define NSTACK_IS_FD_NONBLOCKING(inf) ((inf)->attr & NSTACK_FD_ATTR_NONBLOCKING) -#define NSTACK_SET_FD_NONBLOCKING(inf) ((inf)->attr |= NSTACK_FD_ATTR_NONBLOCKING) -#define NSTACK_SET_FD_BLOCKING(inf) ((inf)->attr &= (~NSTACK_FD_ATTR_NONBLOCKING)) +#define NSTACK_IS_FD_NONBLOKING(inf) ((inf)->attr & NSTACK_FD_ATTR_NONBLOKING) +#define NSTACK_SET_FD_NONBLOKING(inf) ((inf)->attr |= NSTACK_FD_ATTR_NONBLOKING) +#define NSTACK_SET_FD_BLOKING(inf) ((inf)->attr &= (~NSTACK_FD_ATTR_NONBLOKING)) #define NSTACK_IS_FD_EPOLL_SOCKET(inf) ((inf)->attr & NSTACK_FD_ATTR_EPOLL_SOCKET) #define NSTACK_SET_FD_EPOLL_SOCKET(inf) ((inf)->attr |= NSTACK_FD_ATTR_EPOLL_SOCKET) #define NSTACK_IS_FD_LISTEN_SOCKET(inf) ((inf)->attr & NSTACK_FD_ATTR_LISTEN_SOCKET) #define NSTACK_SET_FD_LISTEN_SOCKET(inf) ((inf)->attr |= NSTACK_FD_ATTR_LISTEN_SOCKET) +#define NSTACK_SET_FD_ATTR(inf, _attr) ((inf)->attr |= (_attr)) +#define NSTACK_IS_FD_ATTR(inf, _attr) ((inf)->attr &= (_attr)) + typedef struct { - atomic_t fd_ref; - common_mem_spinlock_t close_lock; - volatile int fd_status; + atomic_t fd_ref; + dmm_spinlock_t close_lock; + volatile int fd_status; } nstack_fd_local_lock_info_t; + /* fd_ref:the number of times the fd is used, when it is 0, should release fd resource close_lock:lock for close and epoll fd_status:when created, it is FD_OPEN;after close, it is FD_CLOSING;after release_fd, it is FD_CLOSE. -- Begin */ +*/ typedef enum { - FD_CLOSE, - FD_OPEN, - FD_CLOSING + FD_CLOSE, + FD_OPEN, + FD_CLOSING } FD_STATUS; typedef enum { - NSTACK_STATE_CLOSE, - NSTACK_STATE_OPEN, - NSTACK_STATE_MAX + NSTACK_STATE_CLOSE, + NSTACK_STATE_OPEN, + NSTACK_STATE_MAX } nstack_fdstate; + typedef struct __nstack_fd_Inf { - ns_int32 rlfd; /*the protocl stack returned fd */ - ns_int32 rmidx; - ns_int32 nxtfd; - nstack_socket_ops *ops; /*opers of the fd, for save space we user opIdx here */ - ns_int32 type; /*the fd type like SOCK_STREAM|SOCK_NONBLOCK ... */ - ns_int32 stat; - ns_int32 fd; - ns_uint32 attr; /* attribute like non-blocking, listen socket , epoll socket.... */ - - nstack_protoFD_t protoFD[NSTACK_MAX_MODULE_NUM]; // where is protocol fd stores, index is module type - nstack_fd_local_lock_info_t local_lock; - /* if has bound to an addr */ - u8_t isBound; /*0:no call bind, 1: call bind */ - char last_reserve[2]; //reserve for update + ns_int32 rlfd; /*the protocl stack returned fd */ + ns_int32 rmidx; + ns_int32 nxtfd; + nstack_socket_ops *ops; /*opers of the fd, for save space we user opIdx here */ + ns_int32 type; /*the fd type like SOCK_STREAM|SOCK_NONBLOCK ... */ + ns_int32 stat; + ns_int32 fd; + ns_uint32 attr; /* attribute like non-blocking, listen socket , epoll socket.... */ + ns_int32 rd_opt; /* select stacks by setsockopt */ + + nstack_protoFD_t protoFD[NSTACK_MAX_MODULE_NUM]; // where is protocol fd stores, index is module type + nstack_fd_local_lock_info_t local_lock; + /* if has bound to an addr */ + u8_t isBound; /*0:no call bind, 1: call bind */ + rd_data_item rd_item; // associated matched rd item + char last_reserve[2]; //reserve for update } nstack_fd_Inf; +// TODO: DFX function +/* +typedef struct __ns_udp_route_info{ + struct sockaddr_in iaddr; + int selectmod; +}ns_udp_route_Inf; +*/ + #define nstack_set_router_protocol(_fdInf, _proto) \ (_fdInf)->rmidx = (_proto); \ nsep_set_infomdix((_fdInf)->fd, (_proto));\ @@ -162,26 +188,25 @@ typedef struct __nstack_fd_Inf #define nstack_set_routed_fd(_fdInf, _protoFD) \ (_fdInf)->rlfd = (_protoFD); \ - nsep_set_infoRlfd((_fdInf)->fd, (_protoFD));\ + nsep_set_info_rlfd((_fdInf)->fd, (_protoFD));\ -nstack_fd_Inf *nstack_fd2inf (int fd); +nstack_fd_Inf *nstack_fd2inf(int fd); -void nstack_reset_fdInf (nstack_fd_Inf * fdInf); +void nstack_reset_fd_inf(nstack_fd_Inf * fdInf); -static inline nstack_fd_Inf * -nstack_getValidInf (int fd) +static inline nstack_fd_Inf *nstack_get_valid_inf(int fd) { - nstack_fd_Inf *retInf = NULL; - retInf = nstack_fd2inf (fd); - if (NULL == retInf || FD_OPEN != retInf->local_lock.fd_status) + nstack_fd_Inf *retInf = NULL; + retInf = nstack_fd2inf(fd); + if (NULL == retInf || FD_OPEN != retInf->local_lock.fd_status) { - return NULL; + return NULL; } - return retInf; + return retInf; } -#define nstack_get_protoFd(fdInf, modInx) ((fdInf)->protoFD[modInx].fd) +#define nstack_get_proto_fd(fdInf, modInx) ((fdInf)->protoFD[modInx].fd) #define nstack_set_bind_ret(fdInf, modInx, ret) ((fdInf)->protoFD[modInx].rslt.brslt = ret) #define nstack_set_listen_ret(fdInf, modInx, ret) ((fdInf)->protoFD[modInx].rslt.lrslt = ret) #define nstack_set_ret(fdInf, modInx, ret) ((fdInf)->protoFD[modInx].pad = ret) @@ -189,17 +214,17 @@ nstack_getValidInf (int fd) #define nstack_get_listen_state(fdInf, modInx) ((fdInf)->protoFD[modInx].liststate) #define nstack_get_listen_ret(fdInf, modInx) ((fdInf)->protoFD[modInx].rslt.lrslt) #define nstack_get_bind_ret(fdInf, modInx) ((fdInf)->protoFD[modInx].rslt.brslt) -#define nstack_get_protoFdSt(fdInf, modInx) (&(fdInf)->protoFD[modInx]) -void nstack_set_protoFd (nstack_fd_Inf * fdInf, int modInx, int protofd); -void nstack_set_app_info (nstack_fd_Inf * fdInf, int modInx); - -int nstack_fd_free_with_kernel (nstack_fd_Inf * fdInf); -int nstack_fd_free_without_kernel (nstack_fd_Inf * fdInf, int ref); -extern nstack_fd_Inf *nstack_lk_fd_alloc_with_kernel (int nfd); //alloc a nstack socket that include kernel fd -extern void nstack_fd_free (nstack_fd_Inf * fdInf); - -void nstack_fork_init_child (pid_t ppid); -void nstack_fork_init_parent (pid_t ppid); +#define nstack_get_proto_fd_st(fdInf, modInx) (&(fdInf)->protoFD[modInx]) +void nstack_set_proto_fd(nstack_fd_Inf * fdInf, int modInx, int protofd); +void nstack_set_app_info(nstack_fd_Inf * fdInf, int modInx); +int nstack_fd_free_with_kernel(nstack_fd_Inf * fdInf); +int nstack_fd_free_without_kernel(nstack_fd_Inf * fdInf, int ref); +extern nstack_fd_Inf *nstack_lk_fd_alloc_with_kernel(int nfd); //alloc a nstack socket that include kernel fd +extern nstack_fd_Inf *nstack_lk_fd_alloc_without_kernel(); +extern void nstack_fd_free(nstack_fd_Inf * fdInf); + +void nstack_fork_init_child(pid_t ppid); +void nstack_fork_fd(pid_t ppid); #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/nSocket/nstack/nstack_info_parse.c b/src/nSocket/nstack/nstack_info_parse.c index 8b2d62f..2f74cf6 100644 --- a/src/nSocket/nstack/nstack_info_parse.c +++ b/src/nSocket/nstack/nstack_info_parse.c @@ -28,6 +28,8 @@ #include "json.h" #include "nsfw_base_linux_api.h" #include "nstack_info_parse.h" +#include "nstack_rd_api.h" +#include "nstack_rd_priv.h" /*get string value*/ #define NSTACK_JSON_PARSE_STRING(obj, name, lent, result, index) do { \ @@ -41,7 +43,7 @@ NSSOC_LOGERR("can't get value from %s index:%d", name, (index)); \ goto RETURN_ERROR; \ } \ - (void)STRNCPY_S((result), (lent), temp_value1, (lent)); \ + (void)strncpy_s((result), (lent), temp_value1, (lent)-1); \ } \ else \ { \ @@ -66,7 +68,7 @@ } \ else \ { \ - if (strcmp(name, "deploytype") == 0 || strcmp(name, "stackid") == 0) \ + if (strcmp(name, "deploytype") == 0 || strcmp(name, "stackid") == 0) \ { \ NSSOC_LOGERR("can't get obj from %s index:%d", name, (index)); \ } \ @@ -77,449 +79,561 @@ } \ } while ( 0 ); -/*parse module cfg*/ -int -nstack_parse_module_cfg_json (char *param) +/* load default config */ +static int load_default_module() { - struct json_object *obj = json_tokener_parse (param); - struct json_object *module_list_obj = NULL; - struct json_object *module_obj = NULL; - struct json_object *temp_obj = NULL; - const char *default_name = NULL; - const char *temp_value = NULL; - int module_num = 0; - int ret = NSTACK_RETURN_FAIL; - int index = 0; - int icnt = 0; - int ret_val; + if (EOK != + strcpy_s(g_nstack_module_desc[0].modName, NSTACK_MODULE_NAME_MAX, + RD_KERNEL_NAME)) + { + NSSOC_LOGERR("strcpy_s failed!"); + return NSTACK_RETURN_FAIL; + } + if (EOK != + strcpy_s(g_nstack_module_desc[0].register_fn_name, + NSTACK_MODULE_NAME_MAX, "kernel_stack_register")) + { + NSSOC_LOGERR("strcpy_s failed!"); + return NSTACK_RETURN_FAIL; + } + if (EOK != + strcpy_s(g_nstack_module_desc[0].libPath, NSTACK_MODULE_NAME_MAX, + "./")) + { + NSSOC_LOGERR("strcpy_s failed!"); + return NSTACK_RETURN_FAIL; + } + g_nstack_module_desc[0].deploytype = NSTACK_MODEL_TYPE1; + g_nstack_module_desc[0].libtype = NSTACK_LIB_LOAD_STATIC; + g_nstack_module_desc[0].default_stack = 1; + g_nstack_module_desc[0].priority = 0; + g_nstack_module_desc[0].maxfdid = 8191; + g_nstack_module_desc[0].minfdid = 0; + g_nstack_module_desc[0].modInx = 0; + + if (EOK != + strcpy_s(g_nstack_module_desc[1].modName, NSTACK_MODULE_NAME_MAX, + "stackpool")) + { + NSSOC_LOGERR("strcpy_s failed!"); + return NSTACK_RETURN_FAIL; + } + if (EOK != + strcpy_s(g_nstack_module_desc[1].register_fn_name, + NSTACK_MODULE_NAME_MAX, "nstack_stack_register")) + { + NSSOC_LOGERR("strcpy_s failed!"); + return NSTACK_RETURN_FAIL; + } + if (EOK != + strcpy_s(g_nstack_module_desc[1].libPath, NSTACK_MODULE_NAME_MAX, + "libnstack.so")) + { + NSSOC_LOGERR("strcpy_s failed!"); + return NSTACK_RETURN_FAIL; + } + g_nstack_module_desc[1].deploytype = NSTACK_MODEL_TYPE3; + g_nstack_module_desc[1].libtype = NSTACK_LIB_LOAD_DYN; + g_nstack_module_desc[1].default_stack = 0; + g_nstack_module_desc[1].priority = 0; + g_nstack_module_desc[1].maxfdid = 8192; + g_nstack_module_desc[1].minfdid = 0; + g_nstack_module_desc[1].modInx = 1; + + g_module_num = 2; + return NSTACK_RETURN_OK; +} - if (!obj) +/*parse module cfg*/ +static int parse_module_cfg(char *param) +{ + struct json_object *obj = json_tokener_parse(param); + struct json_object *module_list_obj = NULL; + struct json_object *module_obj = NULL; + struct json_object *temp_obj = NULL; + const char *default_name = NULL; + const char *temp_value = NULL; + int module_num = 0; + int ret = NSTACK_RETURN_FAIL; + int index = 0; /* local variable:index */ + int icnt = 0; + + if (!obj) { - NSSOC_LOGERR ("json parse fail"); - return NSTACK_RETURN_FAIL; + NSSOC_LOGERR("json parse fail"); + return NSTACK_RETURN_FAIL; } - (void) MEMSET_S (&g_nstack_module_desc[0], sizeof (g_nstack_module_desc), 0, - sizeof (g_nstack_module_desc)); + (void) memset_s(&g_nstack_module_desc[0], sizeof(g_nstack_module_desc), + 0, sizeof(g_nstack_module_desc)); - (void) json_object_object_get_ex (obj, "default_stack_name", &temp_obj); - if (!temp_obj) + (void) json_object_object_get_ex(obj, "default_stack_name", &temp_obj); + if (!temp_obj) { - NSSOC_LOGERR ("can't get module_list"); - goto RETURN_ERROR; + NSSOC_LOGERR("can't get module_list"); + goto RETURN_ERROR; } - default_name = json_object_get_string (temp_obj); + default_name = json_object_get_string(temp_obj); - (void) json_object_object_get_ex (obj, "module_list", &module_list_obj); - if (!module_list_obj) + (void) json_object_object_get_ex(obj, "module_list", &module_list_obj); + if (!module_list_obj) { - NSSOC_LOGERR ("can't get module_list"); - goto RETURN_ERROR; + NSSOC_LOGERR("can't get module_list"); + goto RETURN_ERROR; } - module_num = json_object_array_length (module_list_obj); - if ((module_num <= 0) || (module_num >= NSTACK_MAX_MODULE_NUM)) + module_num = json_object_array_length(module_list_obj); + if ((module_num <= 0) || (module_num >= NSTACK_MAX_MODULE_NUM)) { - NSSOC_LOGERR ("get module number:%d fail", module_num); - goto RETURN_ERROR; + NSSOC_LOGERR("get module number:%d fail", module_num); + goto RETURN_ERROR; } - for (index = 0; index < module_num; index++) + for (index = 0; index < module_num; index++) { - module_obj = json_object_array_get_idx (module_list_obj, index); - if (module_obj) + module_obj = json_object_array_get_idx(module_list_obj, index); + if (module_obj) { - NSTACK_JSON_PARSE_STRING (module_obj, "stack_name", MODULE_NAME_MAX, - &(g_nstack_module_desc[icnt].modName[0]), - index); - STRCPY_S (&(g_nstack_module_desc[icnt].register_fn_name[0]), - sizeof (& - (g_nstack_module_desc[icnt].register_fn_name[0])), - &(g_nstack_module_desc[icnt].modName[0])); - ret_val = - STRCAT_S (&(g_nstack_module_desc[icnt].register_fn_name[0]), - sizeof (& - (g_nstack_module_desc[icnt].register_fn_name - [0])), "_stack_register"); - if (EOK != ret_val) + NSTACK_JSON_PARSE_STRING(module_obj, "stack_name", + NSTACK_MODULE_NAME_MAX, + &(g_nstack_module_desc[icnt].modName + [0]), index); + NSTACK_JSON_PARSE_STRING(module_obj, "function_name", + NSTACK_MODULE_NAME_MAX, + &(g_nstack_module_desc + [icnt].register_fn_name[0]), index); + NSTACK_JSON_PARSE_STRING(module_obj, "libname", + NSTACK_MODULE_NAME_MAX, + &(g_nstack_module_desc[icnt].libPath + [0]), index); + + (void) json_object_object_get_ex(module_obj, "loadtype", + &temp_obj); + if (temp_obj) { - NSFW_LOGERR ("register_fn_name STRCAT_S failed]ret_val=%d", - ret_val); - return -1; - } - NSTACK_JSON_PARSE_STRING (module_obj, "libname", MODULE_NAME_MAX, - &(g_nstack_module_desc[icnt].libPath[0]), - index); - - (void) json_object_object_get_ex (module_obj, "loadtype", - &temp_obj); - if (temp_obj) - { - temp_value = json_object_get_string (temp_obj); - if (strcmp (temp_value, "static") == 0) + temp_value = json_object_get_string(temp_obj); + if (temp_value && (strcmp(temp_value, "static") == 0)) { - g_nstack_module_desc[icnt].libtype = NSTACK_LIB_LOAD_STATIC; + g_nstack_module_desc[icnt].libtype = + NSTACK_LIB_LOAD_STATIC; } - else + else { - g_nstack_module_desc[icnt].libtype = NSTACK_LIB_LOAD_DYN; + g_nstack_module_desc[icnt].libtype = NSTACK_LIB_LOAD_DYN; } } - else + else { - if (strcmp (g_nstack_module_desc[icnt].modName, "kernel") == 0) + if (strcmp + (g_nstack_module_desc[icnt].modName, RD_KERNEL_NAME) == 0) { - g_nstack_module_desc[icnt].libtype = NSTACK_LIB_LOAD_STATIC; + g_nstack_module_desc[icnt].libtype = + NSTACK_LIB_LOAD_STATIC; } - else + else { - g_nstack_module_desc[icnt].libtype = NSTACK_LIB_LOAD_DYN; + g_nstack_module_desc[icnt].libtype = NSTACK_LIB_LOAD_DYN; } - NSSOC_LOGWAR ("can't get the value of loadtype for module:%s", - g_nstack_module_desc[icnt].modName); + NSSOC_LOGWAR("can't get the value of loadtype for module:%s", + g_nstack_module_desc[icnt].modName); } - NSSBR_LOGINF ("load type of %d has been chosen", - g_nstack_module_desc[icnt].libtype); - NSTACK_JSON_PARSE_INT (module_obj, "deploytype", MODULE_NAME_MAX, - g_nstack_module_desc[icnt].deploytype, - index); - NSTACK_JSON_PARSE_INT (module_obj, "maxfd", MODULE_NAME_MAX, - g_nstack_module_desc[icnt].maxfdid, index); - if (g_nstack_module_desc[icnt].maxfdid == 0) + NSTACK_JSON_PARSE_INT(module_obj, "deploytype", + NSTACK_MODULE_NAME_MAX, + g_nstack_module_desc[icnt].deploytype, + index); + g_nstack_module_desc[icnt].maxfdid = 8191; + NSTACK_JSON_PARSE_INT(module_obj, "maxfd", + NSTACK_MODULE_NAME_MAX, + g_nstack_module_desc[icnt].maxfdid, index); + g_nstack_module_desc[icnt].minfdid = 0; + NSTACK_JSON_PARSE_INT(module_obj, "minfd", + NSTACK_MODULE_NAME_MAX, + g_nstack_module_desc[icnt].minfdid, index); + NSTACK_JSON_PARSE_INT(module_obj, "priorty", + NSTACK_MODULE_NAME_MAX, + g_nstack_module_desc[icnt].priority, index); + NSTACK_JSON_PARSE_INT(module_obj, "stackid", + NSTACK_MODULE_NAME_MAX, + g_nstack_module_desc[icnt].modInx, index); + if (icnt != g_nstack_module_desc[icnt].modInx) { - g_nstack_module_desc[icnt].maxfdid = 1024; + NSSOC_LOGERR + ("stackid mismatch, expected:%d, actually given:%d", icnt, + g_nstack_module_desc[icnt].modInx); + goto RETURN_ERROR; } - NSTACK_JSON_PARSE_INT (module_obj, "minfd", MODULE_NAME_MAX, - g_nstack_module_desc[icnt].minfdid, index); - NSTACK_JSON_PARSE_INT (module_obj, "priorty", MODULE_NAME_MAX, - g_nstack_module_desc[icnt].priority, index); - NSTACK_JSON_PARSE_INT (module_obj, "stackid", MODULE_NAME_MAX, - g_nstack_module_desc[icnt].modInx, index); - if (0 == strcmp (g_nstack_module_desc[icnt].modName, default_name)) + if (0 == strcmp(g_nstack_module_desc[icnt].modName, default_name)) { - g_nstack_module_desc[icnt].default_stack = 1; + g_nstack_module_desc[icnt].default_stack = 1; } - icnt++; - g_module_num = icnt; + icnt++; + g_module_num = icnt; } } - ret = NSTACK_RETURN_OK; + ret = NSTACK_RETURN_OK; -RETURN_ERROR: - json_object_put (obj); - return ret; + RETURN_ERROR: + json_object_put(obj); + return ret; } -/*parse module cfg*/ -int -nstack_parse_rd_cfg_json (char *param, rd_route_data ** data, int *num) +static int rd_do_parse(struct json_object *obj, const char *name, void *table) { - struct json_object *obj = json_tokener_parse (param); - struct json_object *ip_list_obj = NULL; - struct json_object *proto_list_obj = NULL; - struct json_object *module_obj = NULL; - struct json_object *temp_obj = NULL; - rd_route_data *rdtemp = NULL; - rd_route_data *rddata = NULL; - const char *sub = NULL; - const char *temp_value = NULL; - int ip_list_num = 0; - int proto_list_num = 0; - int totalnum = 0; - int tlen = 0; - int index = 0; - int icnt = 0; - char ipadd[32] = { 0 }; - - if (!obj) + struct json_object *ip = NULL; + struct json_object *proto = NULL; + struct json_object *type = NULL; + struct json_object *temp = NULL; + struct json_object *o = NULL; + int index = 0; /* local variable:index */ + int ip_list_num = 0, type_list_num = 0, proto_list_num = 0; + const char *ip_addr; + char *sub = NULL; + char addr[32]; + + rd_ip_data ip_data; + rd_type_data type_data; + rd_proto_data proto_data; + + (void) json_object_object_get_ex(obj, "ip_route", &ip); + (void) json_object_object_get_ex(obj, "protocol_route", &proto); + (void) json_object_object_get_ex(obj, "type_route", &type); + if (!ip && !proto && !type) { - NSSOC_LOGERR ("json parse fail"); - return NSTACK_RETURN_FAIL; + NSSOC_LOGERR("Error: no rd policies found!"); + return -1; } - (void) json_object_object_get_ex (obj, "ip_route", &ip_list_obj); - if (!ip_list_obj) + if (ip) + { + ip_list_num = json_object_array_length(ip); + } + if (type) { - NSSOC_LOGERR ("can't get module_list"); - goto RETURN_ERROR; + type_list_num = json_object_array_length(type); } - (void) json_object_object_get_ex (obj, "prot_route", &proto_list_obj); - if (!proto_list_obj) + if (proto) { - NSSOC_LOGERR ("can't get module_list"); - goto RETURN_ERROR; + proto_list_num = json_object_array_length(proto); } - ip_list_num = json_object_array_length (ip_list_obj); - proto_list_num = json_object_array_length (proto_list_obj); - totalnum = ip_list_num + proto_list_num; - if (totalnum > NSTACK_RD_MAX) + for (index = 0; index < ip_list_num; index++) { - NSSOC_LOGERR ("rd num is too more, and return fail"); - goto RETURN_ERROR; + temp = json_object_array_get_idx(ip, index); + if (temp) + { + ip_addr = json_object_get_string(temp); + if (!ip_addr) + { + NSSOC_LOGERR("cannot get ip address at index:%d", index); + return -1; + } + sub = strstr(ip_addr, "/"); + if (!sub) + { + NSSOC_LOGERR("cannot get masklen from %s", ip_addr); + return -1; + } + if (EOK != memset_s(addr, sizeof(addr), 0, sizeof(addr))) + { + NSSOC_LOGERR("memset_s failed!"); + return -1; + } + if (EOK != + strncpy_s(addr, sizeof(addr), ip_addr, + (size_t) (sub - ip_addr))) + { + NSSOC_LOGERR("strncpy_s failed!"); + return -1; + } + ip_data.addr = inet_addr(addr); + ip_data.masklen = atoi(sub + 1); /* not deprecated */ + ip_data.resev[0] = 0; + ip_data.resev[1] = 0; + nstack_rd_ip_node_insert(name, &ip_data, table); + } } - tlen = sizeof (rd_route_data) * totalnum; - rdtemp = (rd_route_data *) malloc (tlen); - if (!rdtemp) + + for (index = 0; index < type_list_num; index++) { - NSSOC_LOGERR ("malloc mem fail"); - goto RETURN_ERROR; + temp = json_object_array_get_idx(type, index); + if (temp) + { + (void) json_object_object_get_ex(temp, "value", &o); + if (!o) + { + NSSOC_LOGERR("no value specified of type_route index:%d", + index); + return -1; + } + type_data.value = json_object_get_int(o); + o = NULL; + (void) json_object_object_get_ex(temp, "attr", &o); + if (!o) + { + NSSOC_LOGERR("no attr specified of type_route index:%d", + index); + return -1; + } + type_data.attr = json_object_get_int(o); + type_data.reserved[0] = 0; + type_data.reserved[1] = 0; + type_data.reserved[2] = 0; + type_data.reserved[3] = 0; + nstack_rd_type_node_insert(name, &type_data, table); + o = NULL; + } } - MEMSET_S (rdtemp, tlen, 0, tlen); - for (index = 0; index < ip_list_num; index++) + + for (index = 0; index < proto_list_num; index++) { - module_obj = json_object_array_get_idx (ip_list_obj, index); - if (module_obj) + temp = json_object_array_get_idx(proto, index); + if (temp) { - rddata = rdtemp + icnt; - rddata->type = RD_DATA_TYPE_IP; - (void) json_object_object_get_ex (module_obj, "stack_name", - &temp_obj); - if (temp_obj) + (void) json_object_object_get_ex(temp, "value", &o); + if (!o) { - temp_value = json_object_get_string (temp_obj); - if (!temp_value) - { - NSSOC_LOGERR ("can't get value from subnet index:%d", - index); - goto RETURN_ERROR; - } - (void) STRNCPY_S (rddata->stack_name, RD_PLANE_NAMELEN, - temp_value, RD_PLANE_NAMELEN); + NSSOC_LOGERR("no value specified of protocol_route index:%d", + index); + return -1; } - (void) json_object_object_get_ex (module_obj, "subnet", &temp_obj); - if (temp_obj) + proto_data.value = json_object_get_int(o); + o = NULL; + (void) json_object_object_get_ex(temp, "attr", &o); + if (!o) { - temp_value = json_object_get_string (temp_obj); - if (!temp_value) - { - NSSOC_LOGERR ("can't get value from subnet index:%d", - index); - goto RETURN_ERROR; - } - sub = strstr (temp_value, "/"); - if (!sub) - { - NSSOC_LOGERR ("can't get maskklen from %s", temp_value); - goto RETURN_ERROR; - } - (void) MEMSET_S (ipadd, sizeof (ipadd), 0, sizeof (ipadd)); - (void) STRNCPY_S (ipadd, sizeof (ipadd), temp_value, - (size_t) (sub - temp_value)); - rddata->ipdata.masklen = atoi (sub + 1); - rddata->ipdata.addr = ntohl (inet_addr (ipadd)); - icnt++; + NSSOC_LOGERR("no attr specified of protocol_route index:%d", + index); + return -1; } + proto_data.attr = json_object_get_int(o); + nstack_rd_proto_node_insert(name, &proto_data, table); + o = NULL; } } - for (index = 0; index < proto_list_num; index++) + return 0; +} + +/*parse rd cfg*/ +static int parse_rd_cfg(char *param, const char *name, void *table) +{ + struct json_object *obj = json_tokener_parse(param); + struct json_object *module_obj = NULL; + struct json_object *temp_obj = NULL; + struct json_object *modules = NULL; + const char *module_name; + int total = 0; + int i = 0; + + if ((!name) || (!obj)) + { + NSSOC_LOGERR("json parse fail"); + return NSTACK_RETURN_FAIL; + } + + (void) json_object_object_get_ex(obj, "modules", &modules); + if (!modules) { - module_obj = json_object_array_get_idx (proto_list_obj, index); - if (module_obj) + NSSOC_LOGERR("can't get modules"); + goto RETURN_ERROR; + } + + total = json_object_array_length(modules); + if (total > NSTACK_MAX_MODULE_NUM) + { + NSSOC_LOGERR("too many modules specified!"); + goto RETURN_ERROR; + } + for (i = 0; i < total; i++) + { + module_obj = json_object_array_get_idx(modules, i); + if (module_obj) { - rddata = rdtemp + icnt; - rddata->type = RD_DATA_TYPE_PROTO; - (void) json_object_object_get_ex (module_obj, "stack_name", - &temp_obj); - if (temp_obj) + (void) json_object_object_get_ex(module_obj, "name", &temp_obj); + if (temp_obj) { - temp_value = json_object_get_string (temp_obj); - if (!temp_value) + module_name = json_object_get_string(temp_obj); + if (!module_name) { - NSSOC_LOGERR ("can't get value from proto index:%d", index); - goto RETURN_ERROR; + NSSOC_LOGERR("cannot get module name at index:%d", i); + goto RETURN_ERROR; } - (void) STRNCPY_S (rddata->stack_name, RD_PLANE_NAMELEN, - temp_value, RD_PLANE_NAMELEN); - } - (void) json_object_object_get_ex (module_obj, "proto_type", - &temp_obj); - if (temp_obj) - { - temp_value = json_object_get_string (temp_obj); - if (!temp_value) + if (strcmp(module_name, name) == 0) // this is what we are looking for { - NSSOC_LOGERR ("can't get value from proto index:%d", index); - goto RETURN_ERROR; + if (rd_do_parse(module_obj, module_name, table)) + { + NSSOC_LOGERR("parse failed at index:%d", i); + goto RETURN_ERROR; + } + break; } - rddata->proto_type = atoi (temp_value); - icnt++; } } } - *data = rdtemp; - *num = icnt; - json_object_put (obj); - return NSTACK_RETURN_OK; -RETURN_ERROR: - json_object_put (obj); - if (rdtemp) - { - free (rdtemp); - } - return -1; + json_object_put(obj); + return NSTACK_RETURN_OK; + RETURN_ERROR: + json_object_put(obj); + return -1; } /*read json file, and return a buf, if return success, the caller need to free **buf*/ -int -nstack_json_file_read (char *filename, char **buf) +static int read_json_file(char *filename, char **buf) { - char *cfg_buf = NULL; - int fp = 0; - off_t file_len = 0; - off_t buff_len = 0; - int ret = NSTACK_RETURN_FAIL; + char *cfg_buf = NULL; + int fp = 0; + off_t file_len = 0; + off_t buff_len = 0; + int ret = NSTACK_RETURN_FAIL; - if ((!filename) || (!buf)) + if ((!filename) || (!buf)) { - return NSTACK_RETURN_FAIL; + return NSTACK_RETURN_FAIL; } - fp = open (filename, O_RDONLY); - if (fp < 0) + fp = open(filename, O_RDONLY); + if (fp < 0) { - NSSOC_LOGERR ("open %s fail, error:%d!", filename, errno); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR("open %s fail, error:%d!", filename, errno); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - file_len = lseek (fp, 0, SEEK_END); - if (file_len <= 0) + file_len = lseek(fp, 0, SEEK_END); + if (file_len <= 0) { - NSSOC_LOGERR ("failed to get file len]file name=%s", filename); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR("failed to get file len]file name=%s", filename); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - if (file_len > NSTACK_CFG_FILELEN_MAX) + if (file_len > NSTACK_CFG_FILELEN_MAX) { - NSSOC_LOGERR - ("file len is too big]file len=%d, max len=%d, file name=%s", - file_len, NSTACK_CFG_FILELEN_MAX, filename); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR + ("file len is too big]file len=%ld, max len=%d, file name=%s", + file_len, NSTACK_CFG_FILELEN_MAX, filename); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - ret = lseek (fp, 0, SEEK_SET); - if (ret < 0) + ret = lseek(fp, 0, SEEK_SET); + if (ret < 0) { - NSSOC_LOGERR ("seek to start failed]file name=%s", filename); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR("seek to start failed]file name=%s", filename); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - buff_len = file_len + 1; - cfg_buf = (char *) malloc (buff_len); - if (!cfg_buf) + buff_len = file_len + 1; + cfg_buf = (char *) malloc(buff_len); + if (!cfg_buf) { - NSSOC_LOGERR ("malloc buff failed]buff_len=%d", buff_len); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR("malloc buff failed]buff_len=%ld", buff_len); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - ret = MEMSET_S (cfg_buf, buff_len, 0, buff_len); - if (NSTACK_RETURN_OK != ret) + ret = memset_s(cfg_buf, buff_len, 0, buff_len); + if (NSTACK_RETURN_OK != ret) { - NSSOC_LOGERR ("MEMSET_S failed]ret=%d.", ret); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR("memset_s failed]ret=%d.", ret); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - ret = nsfw_base_read (fp, cfg_buf, buff_len - 1); - if (ret <= 0) + ret = nsfw_base_read(fp, cfg_buf, buff_len - 1); + if (ret <= 0) { - NSSOC_LOGERR ("read failed]ret=%d, errno:%d", ret, errno); - ret = NSTACK_RETURN_FAIL; - goto RETURN_RELEASE; + NSSOC_LOGERR("read failed]ret=%d, errno:%d", ret, errno); + ret = NSTACK_RETURN_FAIL; + goto RETURN_RELEASE; } - *buf = cfg_buf; - nsfw_base_close (fp); - return NSTACK_RETURN_OK; -RETURN_RELEASE: - if (fp >= 0) + *buf = cfg_buf; + nsfw_base_close(fp); + return NSTACK_RETURN_OK; + RETURN_RELEASE: + if (fp >= 0) { - nsfw_base_close (fp); + nsfw_base_close(fp); } - if (cfg_buf) + if (cfg_buf) { - free (cfg_buf); + free(cfg_buf); } - return ret; + return ret; } /*parse module cfg file*/ -int -nstack_module_parse () +int nstack_module_parse() { - char *modulecfg = NULL; - char *tmp_config_path = NULL; - char *cfg_buf = NULL; - int ret = NSTACK_RETURN_FAIL; + char *modulecfg = NULL; + char *tmp_config_path = NULL; + char *cfg_buf = NULL; + int ret = NSTACK_RETURN_FAIL; - modulecfg = getenv (NSTACK_MOD_CFG_FILE); + modulecfg = getenv(NSTACK_MOD_CFG_FILE); - if (modulecfg) + if (modulecfg) { - tmp_config_path = realpath (modulecfg, NULL); + tmp_config_path = realpath(modulecfg, NULL); } - else + else { - tmp_config_path = realpath (DEFALT_MODULE_CFG_FILE, NULL); + tmp_config_path = realpath(DEFALT_MODULE_CFG_FILE, NULL); } - if (!tmp_config_path) + if (!tmp_config_path) { - NSSOC_LOGERR ("nstack module file:%s get real path fail!", - modulecfg ? modulecfg : DEFALT_MODULE_CFG_FILE); - return NSTACK_RETURN_FAIL; + NSSOC_LOGWAR + ("nstack module file:%s get real path failed! Load default instead.", + modulecfg ? modulecfg : DEFALT_MODULE_CFG_FILE); + return load_default_module(); } - ret = nstack_json_file_read (tmp_config_path, &cfg_buf); - if (NSTACK_RETURN_OK == ret) + ret = read_json_file(tmp_config_path, &cfg_buf); + if (NSTACK_RETURN_OK == ret) { - ret = nstack_parse_module_cfg_json (cfg_buf); - free (cfg_buf); + ret = parse_module_cfg(cfg_buf); + free(cfg_buf); } - free (tmp_config_path); - return ret; + free(tmp_config_path); + return ret; } -int -nstack_stack_rd_parse (rd_route_data ** data, int *num) +int nstack_rd_parse(const char *name, void *table) { - char *modulecfg = NULL; - char *tmp_config_path = NULL; - char *cfg_buf = NULL; - int ret = NSTACK_RETURN_FAIL; + char *modulecfg = NULL; + char *tmp_config_path = NULL; + char *cfg_buf = NULL; + int ret = NSTACK_RETURN_FAIL; - modulecfg = getenv (NSTACK_MOD_CFG_RD); + modulecfg = getenv(NSTACK_MOD_CFG_RD); - if (modulecfg) + if (modulecfg) { - tmp_config_path = realpath (modulecfg, NULL); + tmp_config_path = realpath(modulecfg, NULL); } - else + else { - tmp_config_path = realpath (DEFALT_RD_CFG_FILE, NULL); + tmp_config_path = realpath(DEFALT_RD_CFG_FILE, NULL); } - if (!tmp_config_path) + if (!tmp_config_path) { - NSSOC_LOGERR ("nstack rd file:%s get real path fail!", - modulecfg ? modulecfg : DEFALT_MODULE_CFG_FILE); - return NSTACK_RETURN_FAIL; + NSSOC_LOGWAR("nstack rd file:%s get real path failed!", + modulecfg ? modulecfg : DEFALT_MODULE_CFG_FILE); + return NSTACK_RETURN_FAIL; } - ret = nstack_json_file_read (tmp_config_path, &cfg_buf); - if (NSTACK_RETURN_OK == ret) + ret = read_json_file(tmp_config_path, &cfg_buf); + if (NSTACK_RETURN_OK == ret) { - ret = nstack_parse_rd_cfg_json (cfg_buf, data, num); - free (cfg_buf); + ret = parse_rd_cfg(cfg_buf, name, table); + free(cfg_buf); } - free (tmp_config_path); - return ret; + free(tmp_config_path); + return ret; } diff --git a/src/nSocket/nstack/nstack_info_parse.h b/src/nSocket/nstack/nstack_info_parse.h index 8b508b3..5211dd0 100644 --- a/src/nSocket/nstack/nstack_info_parse.h +++ b/src/nSocket/nstack/nstack_info_parse.h @@ -34,8 +34,6 @@ #include "nstack_module.h" #include "nstack_log.h" #include "nstack_securec.h" -#include "nstack_rd.h" -#include "nstack_rd_data.h" #define DEFALT_MODULE_CFG_FILE "./module_config.json" #define DEFALT_RD_CFG_FILE "./rd_config.json" @@ -50,7 +48,6 @@ extern nstack_module_keys g_nstack_module_desc[NSTACK_MAX_MODULE_NUM]; extern ns_uint32 g_module_num; -extern int nstack_module_parse (); -extern int nstack_stack_rd_parse (rd_route_data ** data, int *num); +extern int nstack_module_parse(); #endif diff --git a/src/nSocket/nstack/nstack_module.c b/src/nSocket/nstack/nstack_module.c index 9566ab8..fdfea06 100644 --- a/src/nSocket/nstack/nstack_module.c +++ b/src/nSocket/nstack/nstack_module.c @@ -29,13 +29,13 @@ #include <arpa/inet.h> #include <errno.h> #include "nstack_module.h" -#include "common_mem_buf.h" #include "nstack_log.h" +#include "nstack_select.h" #include "nstack_securec.h" -#include "nstack_dmm_api.h" -#include "nstack_dmm_adpt.h" -#include "nstack_rd_init.h" +#include "nstack_rd.h" +#include "nstack_epoll_api.h" #include "nstack_info_parse.h" +#include "nsfw_mem_api.h" /* *INDENT-OFF* */ nstack_module_info g_nstack_modules = { @@ -45,243 +45,336 @@ nstack_module_info g_nstack_modules = { .defMod = NULL, }; -/* *INDENT-ON* */ nstack_module_keys g_nstack_module_desc[NSTACK_MAX_MODULE_NUM]; - ns_uint32 g_module_num = 0; +nstack_proc_ops nstack_fd_deal[NSTACK_MAX_MODULE_NUM]; +/* *INDENT-ON* */ + +extern rd_route_table *g_rd_table_handle[NSTACK_MAX_MODULE_NUM]; -int -nstack_get_deploy_type () +int nstack_get_deploy_type() { - int icnt = 0; - int type = 0; - for (icnt = 0; icnt < g_module_num; icnt++) + int icnt = 0; + int type = 0; + for (icnt = 0; icnt < g_module_num; icnt++) { - if (g_nstack_module_desc[icnt].deploytype > type) + if (g_nstack_module_desc[icnt].deploytype > type) { - type = g_nstack_module_desc[icnt].deploytype; + type = g_nstack_module_desc[icnt].deploytype; } } - return type; + return type; } NSTACK_STATIC inline int -nstack_register_one_module (nstack_module_keys * pKeys) +nstack_register_one_module_forchild(nstack_module_keys * pKeys) { + nstack_module *pmod = NULL; + nstack_stack_register_fn stack_register_fn = NULL; + nstack_event_ops val = { 0 }; + int ret = 0; - nstack_module *pmod = NULL; - nstack_stack_register_fn stack_register_fn = NULL; - nstack_event_cb val = { 0 }; - int retVal; - int ret = 0; - - if (pKeys->modInx >= NSTACK_MAX_MODULE_NUM) + if (pKeys->modInx >= NSTACK_MAX_MODULE_NUM) { - NSSOC_LOGERR ("modeindex is overload]index=%d", pKeys->modInx); - ret = -1; - goto err_return; + NSSOC_LOGERR + ("pKeys->modInx is too large]pKeys->modName=%s,pKeys->modInx=%d", + pKeys->modName, pKeys->modInx); + return -1; } - pmod = nstack_get_module (pKeys->modInx); - - retVal = - STRNCPY_S (pmod->modulename, NSTACK_PLUGIN_NAME_LEN, pKeys->modName, - NSTACK_PLUGIN_NAME_LEN); - if (EOK != retVal) + pmod = nstack_get_module(pKeys->modInx); + /*There are some unsafe function ,need to be replace with safe function */ + ret = + strncpy_s(pmod->modulename, NSTACK_MODULE_NAME_MAX, pKeys->modName, + NSTACK_MODULE_NAME_MAX - 1); + if (EOK != ret) { - NSSOC_LOGERR ("STRNCPY_S failed]ret=%d", retVal); - ret = -1; - goto err_return; + NSSOC_LOGERR("strncpy_s failed]ret=%d", ret); + return -1; } + pmod->modulename[NSTACK_MODULE_NAME_MAX - 1] = '\0'; + pmod->priority = pKeys->priority; + pmod->modInx = pKeys->modInx; + pmod->maxfdid = pKeys->maxfdid; + pmod->minfdid = pKeys->minfdid; - pmod->modulename[NSTACK_PLUGIN_NAME_LEN - 1] = '\0'; - pmod->priority = pKeys->priority; - pmod->modInx = pKeys->modInx; - pmod->maxfdid = pKeys->maxfdid; - pmod->minfdid = pKeys->minfdid; - pmod->ep_free_ref = pKeys->ep_free_ref; - - if (pKeys->libtype == NSTACK_LIB_LOAD_DYN) + if (pKeys->libtype == NSTACK_LIB_LOAD_DYN) { - pmod->handle = dlopen (pKeys->libPath, RTLD_LAZY); - if (!pmod->handle) + pmod->handle = dlopen(pKeys->libPath, RTLD_LAZY); + if (!pmod->handle) { - /*optimize dlopen err print */ - NSSOC_LOGERR ("dlopen lib=%s of module=%s failed, err_string=%s", - pKeys->libPath, pKeys->modName, dlerror ()); - ret = -1; - goto err_return; + NSSOC_LOGERR + ("dlopen failed, lib=%s of module=%s, error string=%s", + pKeys->libPath, pKeys->modName, dlerror()); + return -1; } } - else + else { - pmod->handle = RTLD_DEFAULT; + pmod->handle = RTLD_DEFAULT; } - stack_register_fn = dlsym (pmod->handle, pKeys->register_fn_name); - if (!stack_register_fn) + stack_register_fn = dlsym(pmod->handle, pKeys->register_fn_name); + if (!stack_register_fn) { - /* optimize dlopen err print */ - NSSOC_LOGERR ("register function not found]err_string=%s", dlerror ()); - if (pmod->handle) + /* optimize dlopen err print Begin */ + NSSOC_LOGERR("register function not found]err_string=%s", dlerror()); + /* optimize dlopen err print End */ + if (pmod->handle && RTLD_NEXT != pmod->handle) { - dlclose (pmod->handle); - pmod->handle = NULL; + dlclose(pmod->handle); + pmod->handle = NULL; } - ret = -1; - goto err_return; + return -1; } - val.handle = pmod->handle; - val.type = pKeys->modInx; - val.event_cb = nstack_event_callback; - if (stack_register_fn (&pmod->mops, &val)) + val.handle = pmod->handle; + val.type = pKeys->modInx; + val.event_cb = nstack_epoll_event_enqueue; + if (stack_register_fn(&pmod->ops, &val, &nstack_fd_deal[pmod->modInx])) { - NSSOC_LOGERR ("register function failed"); - if (pmod->handle) + NSSOC_LOGERR("register function failed"); + if (pmod->handle && RTLD_NEXT != pmod->handle) { - dlclose (pmod->handle); - pmod->handle = NULL; + dlclose(pmod->handle); + pmod->handle = NULL; } - ret = -1; - goto err_return; + return -1; } - /* malloc length need protect - malloc parameter type is size_t */ - if (((pmod->maxfdid + 1) < 1) - || (SIZE_MAX / sizeof (ns_int32) < (pmod->maxfdid + 1))) + return 0; +} + +void nstack_register_module_forchild(void) +{ + ns_uint32 idx; + for (idx = 0; idx < g_module_num; idx++) { - NSSOC_LOGERR ("malloc size is wrong]maxfdid=%d", pmod->maxfdid); - if (pmod->handle) + if (0 != + nstack_register_one_module_forchild(&g_nstack_module_desc[idx])) { - dlclose (pmod->handle); - pmod->handle = NULL; + NSSOC_LOGERR + ("can't register module]modInx=%d,modName=%s,libPath=%s", + g_nstack_module_desc[idx].modInx, + g_nstack_module_desc[idx].modName, + g_nstack_module_desc[idx].libPath); + return; } - ret = -1; - goto err_return; } - -err_return: - return ret; } -/*nstack_register_module can't concurrent*/ -int -nstack_register_module () +int nstack_register_one_module(nstack_module_keys * pKeys) { - unsigned int idx = 0; - nstack_stack_info *pstacks = NULL; - int ret = 0; - - nstack_get_route_data rd_fun[] = { - nstack_stack_rd_parse, - }; + nstack_module *pmod = NULL; + nstack_stack_register_fn stack_register_fn = NULL; + nstack_event_ops val = { 0 }; + int ret = 0; - pstacks = - (nstack_stack_info *) malloc (sizeof (nstack_stack_info) * g_module_num); - if (!pstacks) + if (pKeys->modInx >= NSTACK_MAX_MODULE_NUM) { - NSSOC_LOGERR ("malloc failed]"); - return ns_fail; + NSSOC_LOGERR("modeindex overflows]index=%d", pKeys->modInx); + ret = -1; + goto err_return; } - ret = - MEMSET_S (pstacks, sizeof (nstack_stack_info) * g_module_num, 0, - sizeof (nstack_stack_info) * g_module_num); - if (EOK != ret) + + pmod = nstack_get_module(pKeys->modInx); + + /*There are some unsafe function ,need to be replace with safe function */ + ret = + strncpy_s(pmod->modulename, NSTACK_MODULE_NAME_MAX, pKeys->modName, + NSTACK_MODULE_NAME_MAX - 1); + if (EOK != ret) { - NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); - free (pstacks); - return ns_fail; + NSSOC_LOGERR("strncpy_s failed]ret=%d", ret); + ret = -1; + goto err_return; } - for (idx = 0; idx < g_module_num; idx++) + pmod->modulename[NSTACK_MODULE_NAME_MAX - 1] = '\0'; + pmod->priority = pKeys->priority; + pmod->modInx = pKeys->modInx; + pmod->maxfdid = pKeys->maxfdid; + pmod->minfdid = pKeys->minfdid; + + if (pKeys->libtype == NSTACK_LIB_LOAD_DYN) { - if (0 != nstack_register_one_module (&g_nstack_module_desc[idx])) + pmod->handle = dlopen(pKeys->libPath, RTLD_LAZY); + if (!pmod->handle) { - NSSOC_LOGERR - ("can't register module]modInx=%d,modName=%s,libPath=%s", - g_nstack_module_desc[idx].modInx, - g_nstack_module_desc[idx].modName, - g_nstack_module_desc[idx].libPath); - free (pstacks); - return ns_fail; + NSSOC_LOGERR + ("dlopen failed, lib=%s of module=%s, error string=%s", + pKeys->libPath, pKeys->modName, dlerror()); + ret = -1; + goto err_return; } - ret = - STRCPY_S (pstacks[idx].name, STACK_NAME_MAX, - g_nstack_module_desc[idx].modName); - if (EOK != ret) + } + else + { + pmod->handle = RTLD_DEFAULT; + } + + stack_register_fn = dlsym(pmod->handle, pKeys->register_fn_name); + if (!stack_register_fn) + { + /* optimize dlopen err print Begin */ + NSSOC_LOGERR("register function not found]err_string=%s", dlerror()); + /* optimize dlopen err print End */ + if (pmod->handle) { - NSSOC_LOGERR ("STRCPY_S fail]idx=%d,modName=%s,ret=%d", idx, - g_nstack_module_desc[idx].modName, ret); - free (pstacks); - return ns_fail; + dlclose(pmod->handle); + pmod->handle = NULL; } - pstacks[idx].priority = g_nstack_module_desc[idx].priority; - pstacks[idx].stack_id = g_nstack_module_desc[idx].modInx; - if (g_nstack_module_desc[idx].default_stack == 1) + ret = -1; + goto err_return; + } + val.handle = pmod->handle; + val.type = pKeys->modInx; + val.event_cb = nstack_epoll_event_enqueue; + if (stack_register_fn(&pmod->ops, &val, &nstack_fd_deal[pmod->modInx])) + { + NSSOC_LOGERR("register function failed, module=%s", pKeys->modName); + if (pmod->handle) { - g_nstack_modules.defMod = - &g_nstack_modules.modules[g_nstack_module_desc[idx].modInx]; - g_nstack_modules.fix_mid = g_nstack_module_desc[idx].modInx; + dlclose(pmod->handle); + pmod->handle = NULL; } + ret = -1; + goto err_return; } - if (g_nstack_modules.fix_mid < 0) + /* malloc length need protect + malloc parameter type is size_t */ + + if (((pmod->maxfdid + 1) < 1) + || (SIZE_MAX / sizeof(ns_int32) < (pmod->maxfdid + 1))) { - free (pstacks); - NSSOC_LOGERR ("nstack fix mid is unknown and return fail"); - return ns_fail; + NSSOC_LOGERR("malloc size is wrong]maxfdid=%d", pmod->maxfdid); + if (pmod->handle) + { + dlclose(pmod->handle); + pmod->handle = NULL; + } + ret = -1; + goto err_return; } - g_nstack_modules.modNum = g_module_num; - /*rd module init */ - if (ns_success != - nstack_rd_init (pstacks, idx, rd_fun, - sizeof (rd_fun) / sizeof (nstack_get_route_data))) + if (nstack_fd_deal[pmod->modInx].module_init_pre) { - free (pstacks); - NSSOC_LOGERR ("nstack rd init fail"); - return ns_fail; + ret = nstack_fd_deal[pmod->modInx].module_init_pre((void *) + g_nsfw_mem_ops, + (void *) + g_ring_ops_arry, + NSFW_MEM_TYPEMAX, + NSFW_MPOOL_TYPEMAX); } - free (pstacks); - return ns_success; + + err_return: + return ret; } -int -nstack_stack_module_init () +/*nstack_register_module can't concurrent*/ +int nstack_register_module() { - ns_uint32 idx; - for (idx = 0; idx < g_module_num; idx++) + unsigned int idx = 0; + nstack_rd_stack_info *pstacks = NULL; + int ret = 0; + + pstacks = + (nstack_rd_stack_info *) malloc(sizeof(nstack_rd_stack_info) * + g_module_num); + if (!pstacks) { - if (g_nstack_modules.modules[idx].mops.extern_ops.module_init) + NSSOC_LOGERR("malloc failed]"); + return ns_fail; + } + /*There are some unsafe function ,need to be replace with safe function */ + ret = + memset_s(&nstack_fd_deal[0], sizeof(nstack_fd_deal), 0, + sizeof(nstack_fd_deal)); + ret |= + memset_s(pstacks, sizeof(nstack_rd_stack_info) * g_module_num, 0, + sizeof(nstack_rd_stack_info) * g_module_num); + if (EOK != ret) + { + NSSOC_LOGERR("memset_s failed]ret=%d", ret); + free(pstacks); /*free() can be used */ + return ns_fail; + } + + for (idx = 0; idx < g_module_num; idx++) + { + if (0 != nstack_register_one_module(&g_nstack_module_desc[idx])) { - if (0 != - g_nstack_modules.modules[idx].mops.extern_ops.module_init ()) - { - NSSOC_LOGERR ("nstack[%s] modx:%d init fail", - g_nstack_modules.modules[idx].modulename, idx); - } + NSSOC_LOGERR + ("can't register module]modInx=%d,modName=%s,libPath=%s", + g_nstack_module_desc[idx].modInx, + g_nstack_module_desc[idx].modName, + g_nstack_module_desc[idx].libPath); + free(pstacks); /*free() can be used */ + return ns_fail; } + ret = + strcpy_s(pstacks[idx].name, STACK_NAME_MAX, + g_nstack_module_desc[idx].modName); + if (EOK != ret) + { + NSSOC_LOGERR("strcpy_s fail]idx=%u,modName=%s,ret=%d", idx, + g_nstack_module_desc[idx].modName, ret); + free(pstacks); /*free() can be used */ + return ns_fail; + } + + pstacks[idx].priority = g_nstack_module_desc[idx].priority; + pstacks[idx].stack_id = g_nstack_module_desc[idx].modInx; + if (g_nstack_module_desc[idx].default_stack == 1) + { + g_nstack_modules.defMod = + &g_nstack_modules.modules[g_nstack_module_desc[idx].modInx]; + g_nstack_modules.fix_mid = g_nstack_module_desc[idx].modInx; + } + if (strcmp(g_nstack_module_desc[idx].modName, RD_KERNEL_NAME) == 0) + { + g_nstack_modules.linuxmid = idx; + } + } + + if (g_nstack_modules.fix_mid < 0) + { + free(pstacks); + NSSOC_LOGERR("nstack fix mid still unknown!"); + return ns_fail; + } + g_nstack_modules.modNum = g_module_num; + + /*rd module init */ + if (ns_success != nstack_rd_init(pstacks, idx)) + { + free(pstacks); /*free() can be used */ + NSSOC_LOGERR("nstack rd init fail"); + return ns_fail; } - return 0; + free(pstacks); /*free() can be used */ + return ns_success; } -int -nstack_stack_module_init_child () +int nstack_stack_module_init() { - ns_uint32 idx; - for (idx = 0; idx < g_module_num; idx++) + int icnt; + for (icnt = 0; icnt < g_module_num; icnt++) { - if (g_nstack_modules.modules[idx].mops.extern_ops.module_init_child) + if (nstack_fd_deal[icnt].module_init) { - if (0 != - g_nstack_modules.modules[idx].mops. - extern_ops.module_init_child ()) + if (nstack_fd_deal[icnt].module_init()) { - NSSOC_LOGERR ("nstack[%s] modx:%d init child fail", - g_nstack_modules.modules[idx].modulename, idx); + NSSOC_LOGERR("stack:%s init failed!", + g_nstack_modules.modules[icnt].modulename); + return -1; } } + if (nstack_fd_deal[icnt].get_ip_shmem) + { + g_rd_table_handle[icnt] = + (rd_route_table *) nstack_fd_deal[icnt].get_ip_shmem(); + } } - return 0; + return 0; } diff --git a/src/nSocket/nstack/nstack_module.h b/src/nSocket/nstack/nstack_module.h index 40a2ef8..1520cf1 100644 --- a/src/nSocket/nstack/nstack_module.h +++ b/src/nSocket/nstack/nstack_module.h @@ -17,12 +17,14 @@ #ifndef __NSTACK_MODULE_H__ #define __NSTACK_MODULE_H__ +#ifndef SPL_INSTANCE_H #include <poll.h> +#endif #include <sys/socket.h> #include <sys/epoll.h> -#include "nstack_types.h" -#include "nstack_dmm_api.h" #include "types.h" +#include "nstack_callback_ops.h" +#include "nsfw_common_defs.h" #ifdef __cplusplus /* *INDENT-OFF* */ @@ -30,60 +32,56 @@ extern "C"{ /* *INDENT-ON* */ #endif -#define NSTACK_LIB_LOAD_DYN 0 -#define NSTACK_LIB_LOAD_STATIC 1 - -#define NSTACK_PLUGIN_NAME_LEN 64 - -#define NSTACK_MAX_MODULE_NUM 8 -#define NSTACK_PRO_MODULE 1 - -#define NSTACK_EP_FREE_NEED_REF 1 /*when epoll information free, need to wait that stack would not notify event */ -#define NSTACK_EP_FREE_NONEED_REF 0 - -#define MODULE_NAME_MAX 128 +#define MOD_INDEX_FOR_STACKPOOL 1 typedef struct __NSTACK_MODULE_KEYS { - ns_char modName[MODULE_NAME_MAX]; /*stack name */ - ns_char register_fn_name[MODULE_NAME_MAX]; /*stack register fun name */ - ns_char libPath[MODULE_NAME_MAX]; /*if libtype is dynamic, it is the path of lib */ - ns_char deploytype; /*delpoly model type: model type1, model type2, model type3 */ - ns_char libtype; /*dynamic lib or static lib */ - ns_char ep_free_ref; /*when epoll information free, - *need to wait that stack would not notify event - */ - ns_char default_stack; /*whether is default stack:when don't know how to choose stack, - *just use default stack - */ - ns_int32 priority; - ns_int32 maxfdid; //the max fd id - ns_int32 minfdid; //the min fd id - ns_int32 modInx; // This is alloced by nStack , not from configuration + ns_char modName[NSTACK_MODULE_NAME_MAX]; // stack name + ns_char register_fn_name[NSTACK_MODULE_NAME_MAX]; // stack register function symbol + ns_char libPath[NSTACK_MODULE_NAME_MAX]; // if libtype is dynamic, it is the path of lib + ns_char deploytype; // deploy type: type1, type2, type3, and etc + ns_char libtype; // dynamic or static + ns_char default_stack; // whether it is the default one + ns_int32 priority; + ns_int32 maxfdid; //the max fd id + ns_int32 minfdid; //the min fd id + ns_int32 modInx; // This is alloced by nStack , not from configuration } nstack_module_keys; typedef struct __NSTACK_MODULE { - char modulename[NSTACK_PLUGIN_NAME_LEN]; - ns_int32 priority; - void *handle; - nstack_proc_cb mops; - ns_int32 ep_free_ref; //ep information need free with ref - ns_int32 modInx; // The index of module - ns_int32 maxfdid; //the max fd id - ns_int32 minfdid; //the min fd id + char modulename[NSTACK_MODULE_NAME_MAX]; + ns_int32 priority; + void *handle; + nstack_socket_ops ops; + ns_int32 modInx; // The index of module + ns_int32 maxfdid; //the max fd id + ns_int32 minfdid; //the min fd id } nstack_module; typedef struct { - ns_int32 modNum; // Number of modules registered - ns_int32 fix_mid; - nstack_module *defMod; // The default module - nstack_module modules[NSTACK_MAX_MODULE_NUM]; + ns_int32 modNum; // Number of modules registed + ns_int32 fix_mid; + ns_int32 linuxmid; + nstack_module *defMod; // The default module + nstack_module modules[NSTACK_MAX_MODULE_NUM]; } nstack_module_info; +typedef enum +{ + NSTACK_MODEL_TYPE1 = 1, /*nSocket and stack belong to the same process */ + NSTACK_MODEL_TYPE2 = 2, /*nSocket and stack belong to different processes, + *and nStack don't take care the communication between stack and stack adpt + */ + NSTACK_MODEL_TYPE3 = 3, /*nSocket and stack belong to different processes, and sbr was supplied to communicate whit stack */ + NSTACK_MODEL_TYPE_SIMPLE_STACK = 4, /* like TYPE1, DMM will NOT provide SBR or pipeline mode, just allocate 32M, and use dpdk file + * prefix to support multiple running app under DMM */ + NSTACK_MODEL_INVALID, +} nstack_model_deploy_type; + /*register module according the modulecfg file*/ -extern ns_int nstack_register_module (); +extern ns_int nstack_register_module(); /***************************************************************** Parameters : ops never be null; nstack api calls it; @@ -91,48 +89,39 @@ Return : 0,not match; 1, match Description : *****************************************************************/ extern nstack_module_info g_nstack_modules; +extern nstack_proc_ops nstack_fd_deal[NSTACK_MAX_MODULE_NUM]; extern nstack_module_keys g_nstack_module_desc[]; +extern ns_uint32 g_module_num; #define nstack_defmod_name() (g_nstack_modules.defMod->modulename) #define nstack_default_module() (g_nstack_modules.defMod) -#define nstack_defMod_inx() (g_nstack_modules.defMod->modInx) +#define nstack_defmod_inx() (g_nstack_modules.fix_mid) #define nstack_get_module(inx) (&g_nstack_modules.modules[(inx)]) -#define nstack_get_modNum() (g_nstack_modules.modNum) +#define nstack_get_module_num() (g_nstack_modules.modNum) #define nstack_get_module_name_by_idx(inx) (g_nstack_modules.modules[inx].modulename) -#define nstack_def_ops() (&g_nstack_modules.defMod->mops.socket_ops) -#define nstack_module_ops(modInx) (&g_nstack_modules.modules[(modInx)].mops.socket_ops) +#define nstack_def_ops() (&g_nstack_modules.defMod->ops) +#define nstack_get_linux_mid() (g_nstack_modules.linuxmid) +#define nstack_module_ops(modInx) (&g_nstack_modules.modules[(modInx)].ops) #define nstack_get_maxfd_id(modInx) (g_nstack_modules.modules[modInx].maxfdid) #define nstack_get_minfd_id(modInx) (g_nstack_modules.modules[modInx].minfdid) -#define nstack_get_descmaxfd_id(modInx) (g_nstack_module_desc[modInx].maxfdid) -#define nstack_epinfo_free_flag(modInx) (g_nstack_modules.modules[(modInx)].ep_free_ref == NSTACK_EP_FREE_NEED_REF) - -#define nstack_extern_deal(modInx) (g_nstack_modules.modules[(modInx)].mops.extern_ops) +#define nstack_set_maxfd_id(modInx, maxfd) (g_nstack_module_desc[modInx].maxfdid = maxfd) -#define nstack_defMod_profd(fdInf) ((fdInf)->protoFD[g_nstack_modules.defMod->modInx].fd) -#define nstack_inf_modProfd(fdInf, pMod) ((fdInf)->protoFD[(pMod)->modInx].fd) +#define nstack_def_mod_profd(fdInf) ((fdInf)->protoFD[g_nstack_modules.defMod->modInx].fd) +#define nstack_inf_mod_profd(fdInf, pMod) ((fdInf)->protoFD[(pMod)->modInx].fd) -#define nstack_get_fix_mid() (g_nstack_modules.fix_mid) -#define nstack_fix_mid_ops() (&(g_nstack_modules.modules[g_nstack_modules.fix_mid].mops.socket_ops)) -#define nstack_fix_stack_name() (g_nstack_modules.modules[g_nstack_modules.fix_mid].modulename) +#define nstack_each_mod_ops(modInx, ops) \ + for ((modInx) = 0; ((modInx) < nstack_get_module_num() && ((ops) = nstack_module_ops(modInx))); (modInx)++) -#define nstack_fix_fd_check() ((g_nstack_modules.fix_mid >= 0) && (g_nstack_modules.fix_mid < NSTACK_MAX_MODULE_NUM) \ - ? g_nstack_modules.modules[g_nstack_modules.fix_mid].mops.extern_ops.stack_fd_check \ - : NULL) - -#define nstack_each_modOps(modInx, ops) \ - for ((modInx) = 0; ((modInx) < nstack_get_modNum() && ((ops) = nstack_module_ops(modInx))); (modInx)++) - -#define nstack_each_modInx(modInx) \ - for ((modInx) = 0; ((modInx) < nstack_get_modNum()); (modInx)++) +#define nstack_each_mod_inx(modInx) \ + for ((modInx) = 0; ((modInx) < nstack_get_module_num()); (modInx)++) #define nstack_each_module(modInx, pMod) \ - for ((modInx) = 0; ((modInx) < nstack_get_modNum() && (pMod = nstack_get_module((modInx)))); (modInx)++) - -int nstack_stack_module_init (); -int nstack_stack_module_init_child (); + for ((modInx) = 0; ((modInx) < nstack_get_module_num() && (pMod = nstack_get_module((modInx)))); (modInx)++) -int nstack_get_deploy_type (); +void nstack_register_module_forchild(void); +int nstack_get_deploy_type(); +int nstack_stack_module_init(); #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/nSocket/nstack/nstack_nsocket_construct.c b/src/nSocket/nstack/nstack_nsocket_construct.c index 0b447b7..bf60066 100644 --- a/src/nSocket/nstack/nstack_nsocket_construct.c +++ b/src/nSocket/nstack/nstack_nsocket_construct.c @@ -14,30 +14,20 @@ * limitations under the License. */ -#include "nsfw_init.h" +#include "nsfw_init_api.h" #include "nsfw_mem_api.h" #include "nsfw_mgr_com_api.h" #include "nsfw_recycle_api.h" -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C"{ -/* *INDENT-ON* */ -#endif /* __cplusplus */ - #define NSACK_NSOCKET_MODULE "nSocket" -extern int nstack_app_init (void *ppara); -/* *INDENT-OFF* */ -NSFW_MODULE_NAME (NSACK_NSOCKET_MODULE) -NSFW_MODULE_PRIORITY (7) -NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE) -NSFW_MODULE_DEPENDS (NSFW_MEM_MGR_MODULE) -NSFW_MODULE_DEPENDS (NSFW_RECYCLE_MODULE) -NSFW_MODULE_INIT (nstack_app_init) -/* *INDENT-ON* */ -#ifdef __cplusplus +extern int nstack_app_init(void *ppara); + /* *INDENT-OFF* */ -} +NSFW_MODULE_NAME(NSACK_NSOCKET_MODULE) +NSFW_MODULE_PRIORITY(7) +NSFW_MODULE_DEPENDS(NSFW_MGR_COM_MODULE) +NSFW_MODULE_DEPENDS(NSFW_MEM_MGR_MODULE) +NSFW_MODULE_DEPENDS(NSFW_RECYCLE_MODULE) +NSFW_MODULE_INIT(nstack_app_init) /* *INDENT-ON* */ -#endif /* __cplusplus */ diff --git a/src/nSocket/nstack/nstack_socket.c b/src/nSocket/nstack/nstack_socket.c index 210e29d..a69747d 100644 --- a/src/nSocket/nstack/nstack_socket.c +++ b/src/nSocket/nstack/nstack_socket.c @@ -31,12 +31,11 @@ #include "nstack.h" #include "nstack_socket.h" #include "nstack_fd_mng.h" -#include "nstack_dmm_api.h" +#include "nstack_callback_ops.h" #include "nstack_sockops.h" #include "nstack_module.h" -#include "common_mem_spinlock.h" #include "nstack_securec.h" -#include "nsfw_init.h" +#include "nsfw_init_api.h" #include "nsfw_recycle_api.h" #include "nsfw_base_linux_api.h" #include "nstack_rd_data.h" @@ -44,8 +43,17 @@ #include "select_adapt.h" #include "nstack_select.h" #include "nstack_share_res.h" +#include "nsfw_ps_api.h" +#include "nstack_ip_addr.h" +#include "nsfw_mem_api.h" +#include "dmm_spinlock.h" +#include "dmm_rwlock.h" +#include "nstack_dmm_dfx.h" +#include <stdlib.h> +#include <unistd.h> + #ifndef F_SETFL -#define F_SETFL 4 +#define F_SETFL 4 #endif #define NSTACK_LOOP_IP 0x100007f @@ -60,8 +68,12 @@ extern __typeof (name) aliasname __attribute__ ((alias (#name))); #undef NSTACK_MK_DECL #define NSTACK_MK_DECL(ret, fn, args) strong_alias(nstack_##fn, fn) -#include <declare_syscalls.h> +#include <declare_syscalls.h.tmpl> #endif +__thread unsigned int g_addrinfo_flag = 0; + +extern void nsep_notify_fd_epoll_wait_fail(struct eventpoll *ep); +extern void custom_close_status(int fd, int status); #define NSTACK_FUN_CHECK_RET(fdops, mod, fun) \ if (!(fdops) || !(fdops)->pf##fun) \ @@ -71,34 +83,40 @@ return -1; \ } -#define NSTACK_DOMAIN_CHECK_RET(domainVal, fn, para) { \ - if ((domainVal != AF_INET) \ - && (domainVal != PF_INET)) \ - { \ - int _ret_ = 0; \ - if (nstack_fix_fd_check() && nstack_fix_fd_check()(-1, STACK_FD_FUNCALL_CHECK)) \ +#define NSTACK_DOMAIN_CHECK_RETURN(domainVal, fn, para) { \ + if (domainVal != AF_INET && domainVal != PF_INET && \ + domainVal != AF_INET6 && domainVal != PF_INET6) \ { \ - NSTACK_CAL_FUN(nstack_fix_mid_ops(), fn, para, _ret_); \ + int _ret_ = nsfw_base_socket para ; \ + return _ret_; \ } \ - return _ret_; \ - } \ + } + +#define NSTACK_ADDRINFO_CHECK_RETURN(flag, fn, para){\ + if (1 == flag) \ + {\ + NSSOC_LOGINF("linux getaddrinfo [call]");\ + return nsfw_base_##fn para ; \ + }\ +} + +NSTACK_STATIC inline int support_kernel_fd() +{ +#ifdef KERNEL_FD_SUPPORT + return 1; +#else + return 0; +#endif } -#define NSTACK_FD_LINUX_CHECK(fdVal, fn, fdInf, para) { \ - if (!(fdInf = nstack_getValidInf(fdVal))) \ +/* fork will close all fd(dont create by nstack) in continure, + which cause lots of log, here remove the log output */ +#define NSTACK_FD_LINUX_CHECK_RETURN(fdVal, fn, fdInf, para) { \ + if (!(fdInf = nstack_get_valid_inf(fdVal))) \ { \ - if (NSTACK_THREAD_LOADING()) \ - { \ - return nsfw_base_##fn para;\ - } \ - if (0 == nstack_stack_module_load()) \ - { \ - if (nstack_fix_fd_check() && nstack_fix_fd_check()(fdVal, STACK_FD_FUNCALL_CHECK)) \ - { \ - int _ret_ = 0; \ - NSTACK_CAL_FUN(nstack_fix_mid_ops(), fn, para, _ret_); \ - return _ret_; \ - } \ + if ((support_kernel_fd()) && (fdVal != nsep_get_manager()->checkEpollFD)) \ + { \ + return nsfw_base_##fn para; \ } \ nstack_set_errno(ENOSYS); \ return -1; \ @@ -107,1540 +125,1913 @@ #define NSTACK_SELECT_LINUX_CHECK() (get_select_module()->inited) -/* Supports multi-threaded and multi-process */ -NSTACK_STATIC inline void -set_fd_status (int fd, FD_STATUS status) +/* Support multi-threaded and multi-process */ +NSTACK_STATIC inline void set_fd_status(int fd, FD_STATUS status) { - nstack_fd_local_lock_info_t *local_lock = get_fd_local_lock_info (fd); - if (local_lock) + nstack_fd_local_lock_info_t *local_lock = get_fd_local_lock_info(fd); + if (local_lock) { - if (FD_OPEN == status) + if (FD_OPEN == status) { - atomic_inc (&local_lock->fd_ref); + atomic_inc(&local_lock->fd_ref); } - local_lock->fd_status = status; + local_lock->fd_status = (int) status; } } -void -set_fd_status_lock_fork (int fd, FD_STATUS status) +#define LOCK_SEND(fd, fd_inf, local_lock) \ + u64_t tmp_in; /* use tmp_in to avoid statistic mistake from the lock acquiring */ \ + NSTACK_GET_SYS_TICK(&tmp_in);\ + INC_FD_REF_RETURN(fd, fd_inf, local_lock) \ + NSTACK_FD_DFX_LAST_SEND_TICK_IN(fd, tmp_in) + +static inline void UNLOCK_SEND(int fd, nstack_fd_Inf * fdInf, + nstack_fd_local_lock_info_t * local_lock) { - common_mem_rwlock_read_lock (get_fork_lock ()); - set_fd_status (fd, status); - common_mem_rwlock_read_unlock (get_fork_lock ()); + u64_t tmp_out; + NSTACK_GET_SYS_TICK(&tmp_out); + NSTACK_FD_DFX_LAST_SEND_TICK_OUT(fd, tmp_out); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_COST, NULL); + if ((NULL != local_lock) && atomic_dec(&local_lock->fd_ref) == 0) + { + release_fd(fd, local_lock); + } } -/***************************************************************** -Parameters : domain - type - protocol -Return : -Description : create a nstack fd for application -*****************************************************************/ -int -nstack_socket (int domain, int itype, int protocol) +#define LOCK_RECV(fd, fd_inf, local_lock) \ + u64_t tmp_in; /* use tmp_in to avoid statistic mistake from the lock acquiring */ \ + NSTACK_GET_SYS_TICK(&tmp_in);\ + LOCK_BASE_WITHOUT_KERNEL(fd, fd_inf, local_lock) \ + NSTACK_FD_DFX_LAST_RECV_TICK_IN(fd, tmp_in) + +static inline void UNLOCK_RECV(int fd, nstack_fd_Inf * fdInf, + nstack_fd_local_lock_info_t * local_lock) { - int ret = -1; //tmp ret of a Single proctol mode. - int modInx; - nstack_socket_ops *ops; - int ret_fd = -1; - int protoFD[NSTACK_MAX_MODULE_NUM]; - int selectmod = -1; - - /*check whether module init finish or not */ - NSTACK_INIT_CHECK_RET (socket, domain, itype, protocol); - - NSSOC_LOGINF ("(domain=%d, type=%d, protocol=%d) [Caller]", domain, itype, - protocol); - - /*if domain don't equal AF_INET , just call linux */ - NSTACK_DOMAIN_CHECK_RET (domain, socket, (domain, itype, protocol)); - - nstack_each_modInx (modInx) - { - protoFD[modInx] = -1; - } - - /*create the fix socket first, and check it wether ok */ - NSTACK_CAL_FUN (nstack_fix_mid_ops (), socket, (domain, itype, protocol), - ret_fd); - if (!nstack_is_nstack_sk (ret_fd)) - { - if (ret_fd >= 0) - { - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (ret_fd), ret); - nstack_set_errno (EMFILE); - } - NSSOC_LOGERR - ("[nstack_linux]domain=%d,type=%d protocol=%d linux fd=%d is too big and return fail [return]", - domain, itype, protocol, ret_fd); - return ns_fail; - } - - protoFD[nstack_get_fix_mid ()] = ret_fd; - - nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info (ret_fd); - LOCK_FOR_EP (lock_info); - /*create socket by calling select module or all module */ - nstack_each_modOps (modInx, ops) - { - if (modInx == nstack_get_fix_mid ()) - { - continue; - } - /*if no module selected then create all or just create selected stack */ - if ((selectmod == -1) || (modInx == selectmod)) - { - NSTACK_CAL_FUN (ops, socket, (domain, itype, protocol), ret); - protoFD[modInx] = ret; - NSSOC_LOGINF ("Create socket of]modName=%s:%d", - nstack_get_module_name_by_idx (modInx), - protoFD[modInx]); - if ((modInx == selectmod) && (-1 == ret)) - { - goto SOCKET_ERR; - } - } - } - - /* alloc nstack fd info */ - nstack_fd_Inf *fdInf = nstack_lk_fd_alloc_with_kernel (ret_fd); - if (NULL == fdInf) - { - /*if alloc failed */ - nstack_set_errno (EMFILE); - NSSOC_LOGERR ("have no available nstack_fd_Inf [return]"); - goto SOCKET_ERR; - } - - /*save the fd into fdinfo */ - fdInf->type = itype; - nstack_each_modInx (modInx) - { - if (-1 != protoFD[modInx]) - { - nstack_set_ret (fdInf, modInx, 0); - nstack_set_protoFd (fdInf, modInx, protoFD[modInx]); - nstack_set_app_info (fdInf, modInx); - } - } - set_fd_status_lock_fork (ret_fd, FD_OPEN); - - /*if some stack was choose, just set the chose stack */ - if (-1 != selectmod) - { - fdInf->ops = nstack_module_ops (selectmod); - nstack_set_router_protocol (fdInf, selectmod); - nstack_set_routed_fd (fdInf, protoFD[selectmod]); - } - NSSOC_LOGINF ("create fix stack[%s] fd=%d,fdInf->fd=%d,ret=%d [return]", - nstack_fix_stack_name (), ret_fd, fdInf->fd, ret_fd); - UNLOCK_FOR_EP (lock_info); - return ret_fd; - -SOCKET_ERR: - nstack_each_modOps (modInx, ops) - { - if (-1 != protoFD[modInx]) - { - NSTACK_CAL_FUN (ops, close, (protoFD[modInx]), ret); - } - } - UNLOCK_FOR_EP (lock_info); - return -1; + u64_t tmp_out; + NSTACK_GET_SYS_TICK(&tmp_out); + NSTACK_FD_DFX_LAST_RECV_TICK_OUT(fd, tmp_out); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_COST, NULL); + /*do not need return value */ UNLOCK_BASE(fd, fdInf, local_lock); } -/***************************************************************** -Parameters : fd - addr - len -Return : -Description : the code of bind&listen are same, if there are another same api we should extract -*****************************************************************/ -int -nstack_bind (int fd, const struct sockaddr *addr, socklen_t addrlen) +#define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fdVal, fun, inf, err, local_lock) \ + /*do not need return value*/NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_SEND) + +#define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fdVal, fun, inf, err, local_lock) \ + /*do not need return value*/NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_RECV) + +void set_fd_status_lock_fork(int fd, FD_STATUS status) { - nstack_fd_Inf *fdInf; - int retval = ns_fail; - int tem = -1; - int modIdx = 0; - int tfd; - int selectmod = -1; - struct sockaddr_in *iaddr = NULL; - nstack_rd_key rdkey = { 0 }; + dmm_read_lock(get_fork_lock()); + set_fd_status(fd, status); + dmm_read_unlock(get_fork_lock()); +} - NSTACK_INIT_CHECK_RET (bind, fd, addr, addrlen); +/* Implemet aggregation packets send/receive. */ - NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, - addrlen); +int nstack_create_kernel_socket() +{ + return nsfw_base_socket(AF_UNIX, SOCK_DGRAM, 0); +} - if (fd < 0) - { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d,addr=%p,len=0x%x [return]", fd, addr, - addrlen); - return -1; - } - if ((NULL == addr) || (addrlen < 2)) +int nstack_socket_create_index(int domain, int itype, int protocol, + rd_data_item * matched_item) +{ + int ret_fd; + if (nstack_rd_match_pre(domain, itype, protocol, matched_item) == -1) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("invalid input]fd=%d,addr=%p,len=0x%x [return]", fd, addr, - addrlen); - return -1; + return nsfw_base_socket(domain, itype, protocol); } - iaddr = (struct sockaddr_in *) addr; - if ((addrlen >= sizeof (struct sockaddr_in)) - && ((addr->sa_family) == AF_INET)) + //NSTACK_CAL_FUN(nstack_module_ops(matched_item.stack_id), socket, (domain, itype, protocol), ret_fd); + ret_fd = nstack_create_kernel_socket(); + + return ret_fd; +} + +int nstack_socket(int domain, int itype, int protocol) +{ + int ret = -1; //tmp ret of a Single proctol mode. + int modInx; + nstack_socket_ops *ops; + int ret_fd = -1; + int protoFD[NSTACK_MAX_MODULE_NUM]; + rd_data_item matched_item = { + .stack_id = -1 + }; + + /*check whether module init finish or not */ + NSTACK_INIT_CHECK_RET(socket, domain, itype, protocol); + + NSSOC_LOGINF("(domain=%d, type=%d, protocol=%d) [Caller]", domain, itype, + protocol); + +#ifndef KERNEL_FD_SUPPORT + if (domain != AF_INET && domain != PF_INET && domain != AF_INET6) { - NSSOC_LOGINF ("fd=%d,addr=%s,port=%d", fd, inet_ntoa (iaddr->sin_addr), - ntohs (iaddr->sin_port)); + NSSOC_LOGERR("don't support the specified address family.]domain=%d", + domain); + nstack_set_errno(EAFNOSUPPORT); + return ns_fail; } - else + + if (protocol < 0) { - NSSOC_LOGINF ("addrlen = %d ,fd=%d", (int) addrlen, fd); + nstack_set_errno(EINVAL); + return ns_fail; } +#endif - NSTACK_FD_LINUX_CHECK (fd, bind, fdInf, (fd, addr, addrlen)); + /*if domain don't equal AF_INET , just call linux */ + NSTACK_DOMAIN_CHECK_RETURN(domain, socket, (domain, itype, protocol)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); + /* if the socket is called by getaddrinfo, just call linux */ + NSTACK_ADDRINFO_CHECK_RETURN(g_addrinfo_flag, socket, + (domain, itype, protocol)); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON (fd, bind, fdInf, ENOTSOCK, - local_lock); + nstack_each_mod_inx(modInx) + { + protoFD[modInx] = -1; + } - /*bind repeat, first time success, other return fail */ - if (fdInf->isBound) +#ifdef KERNEL_FD_SUPPORT + /*firstly create linux fd, if create fail or fd is too big just return fail */ + ret_fd = + nstack_socket_create_index(domain, itype, protocol, &matched_item); + if (-1 == ret_fd) { - nstack_set_errno (EINVAL); - NSPOL_LOGERR ("error, already bind]fd=%d", fd); - UNLOCK_COMMON (fd, local_lock); - return -1; + NSSOC_LOGERR + ("[nstack_linux]domain=%d,type=%d protocol=%d create fail errno:%d [return]", + domain, itype, protocol, errno); + return ns_fail; } - /*just support af_inet and pf_inet */ - if (iaddr->sin_family != AF_INET && iaddr->sin_family != PF_INET) + /*linux fd is to big, return fail */ + if (!nstack_is_nstack_sk(ret_fd)) { - nstack_set_errno (EAFNOSUPPORT); - NSSOC_LOGERR ("not surport]fd=%d,domain=%d,[return]", fd, - iaddr->sin_family); - UNLOCK_COMMON (fd, local_lock); - return -1; + if (ret_fd >= 0) + { + nsfw_base_close(ret_fd); /*donot need return value */ + } + nstack_set_errno(EMFILE); + NSSOC_LOGERR + ("[nstack_linux]domain=%d,type=%d protocol=%d linux fd=%d is too big and return fail [return]", + domain, itype, protocol, ret_fd); + return ns_fail; } - /* need check addrlen's validity, will visite iaddr->sin_addr.s_addr following code - for visite iaddr->sin_addr.s_addr is 8 byte */ - if (addrlen < 8) + nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info(ret_fd); + LOCK_FOR_EP(lock_info); + + protoFD[nstack_get_linux_mid()] = ret_fd; // Set kernel fd here. +#endif + + /*create socket by calling every module */ + nstack_each_mod_ops(modInx, ops) { - nstack_set_errno (EINVAL); - NSPOL_LOGERR ("addrlen<sizeof(struct sockaddr_in)]addrlen=%u", addrlen); - UNLOCK_COMMON (fd, local_lock); - return -1; +#ifdef KERNEL_FD_SUPPORT + if (modInx == nstack_get_linux_mid()) + continue; +#endif + NSTACK_CAL_FUN(ops, socket, (domain, itype, protocol), ret); + protoFD[modInx] = ret; + NSSOC_LOGINF("Create socket of]modName=%s:%d", + nstack_get_module_name_by_idx(modInx), protoFD[modInx]); } - /* for custom socket, choose stack after creating socket. */ - if (fdInf->ops) + /* alloc nstack fd info */ +#ifdef KERNEL_FD_SUPPORT + nstack_fd_Inf *fdInf = nstack_lk_fd_alloc_with_kernel(ret_fd); +#else + nstack_fd_Inf *fdInf = nstack_lk_fd_alloc_without_kernel(); +#endif + if (NULL == fdInf) { - NSTACK_CAL_FUN (fdInf->ops, bind, (fdInf->rlfd, addr, addrlen), tem); - if (ns_success == tem) + /*if alloc failed */ + nstack_each_mod_ops(modInx, ops) { - retval = ns_success; - nstack_set_bind_ret (fdInf, fdInf->rmidx, NSTACK_BIND_SUCCESS); - } - else - { - nstack_set_bind_ret (fdInf, fdInf->rmidx, NSTACK_BIND_FAIL); + if (-1 != protoFD[modInx]) + { + NSTACK_CAL_FUN(ops, close, (protoFD[modInx]), ret); + } } - goto bind_over; + + nstack_set_errno(EMFILE); + NSSOC_LOGERR("have no available nstack_fd_Inf [return]"); +#ifdef KERNEL_FD_SUPPORT + UNLOCK_FOR_EP(lock_info); +#endif + return -1; } +#ifndef KERNEL_FD_SUPPORT + nstack_fd_local_lock_info_t *lock_info = + get_fd_local_lock_info(fdInf->fd); + LOCK_FOR_EP(lock_info); +#endif + fdInf->type = itype; + fdInf->rd_opt = -1; + fdInf->rd_item.stack_id = -1; - /*loop ip call linux */ - rdkey.type = RD_DATA_TYPE_IP; - rdkey.ip_addr = iaddr->sin_addr.s_addr; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((ns_success != retval) && (-1 != selectmod)) + if (matched_item.stack_id != -1) { - NSSOC_LOGWAR ("fd Can't select any module for]fd=%d,IP==%s", fd, - inet_ntoa ((iaddr->sin_addr))); - selectmod = -1; + if (EOK != + memcpy_s(&fdInf->rd_item, sizeof(rd_data_item), &matched_item, + sizeof(rd_data_item))) + { + NSSOC_LOGERR("memcpy_s failed!"); + nstack_set_errno(EMFILE); + return -1; + } } - else + nstack_each_mod_inx(modInx) { - NSSOC_LOGINF ("fd addr Select module]fd=%d,addr=%s,module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - } +#ifndef KERNEL_FD_SUPPORT + //if (modInx == nstack_get_linux_mid()) + //continue; +#endif + nstack_set_ret(fdInf, modInx, 0); + nstack_set_proto_fd(fdInf, modInx, protoFD[modInx]); + nstack_set_app_info(fdInf, modInx); + } + +#ifdef KERNEL_FD_SUPPORT + NSSOC_LOGINF("createfd=%d,fdInf->fd=%d,ret=%d [return]", ret_fd, + fdInf->fd, ret_fd); + set_fd_status_lock_fork(ret_fd, FD_OPEN); +#else + NSSOC_LOGINF("fdInf->fd=%d,ret=%d [return]", fdInf->fd, fdInf->fd); + set_fd_status_lock_fork(fdInf->fd, FD_OPEN); + ret_fd = fdInf->fd; +#endif - if (selectmod == -1) +#ifdef KERNEL_FD_SUPPORT + if (matched_item.stack_id != -1) { - rdkey.type = RD_DATA_TYPE_PROTO; - rdkey.proto_type = fdInf->type; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod < 0) - || (selectmod >= nstack_get_modNum ())) - { - NSSOC_LOGWAR - ("fd Can't select any module for]fd=%d,IP==%s using proto route", - fd, inet_ntoa ((iaddr->sin_addr))); - selectmod = -1; - } - else + switch (matched_item.type) { - NSSOC_LOGINF ("Bind socket of]select modName=%s", - nstack_get_module_name_by_idx (selectmod)); + case RD_DATA_TYPE_TYPE: + { + NSTACK_SET_FD_ATTR(fdInf, matched_item.type_data.attr); + break; + } + case RD_DATA_TYPE_PROTO: + { + NSTACK_SET_FD_ATTR(fdInf, matched_item.proto_data.attr); + break; + } + default: + break; } + fdInf->ops = nstack_module_ops(matched_item.stack_id); + nstack_set_router_protocol(fdInf, matched_item.stack_id); + nstack_set_routed_fd(fdInf, protoFD[matched_item.stack_id]); } +#endif - retval = -1; - nstack_each_modInx (modIdx) - { - tfd = nstack_get_protoFd (fdInf, modIdx); - if ((-1 == tfd) || (selectmod != modIdx)) // for INADDR_ANY, need try to bind on both stack-x and linux - { - /*tfd is -1, but is the select module */ - if (selectmod == modIdx) - { - retval = -1; - nstack_set_errno (ENOSYS); - NSSOC_LOGDBG - ("fd tfd=-1, but is the select module]fd=%d,tfd=-1,modIdx=%d", - fd, modIdx); - } - nstack_set_bind_ret (fdInf, modIdx, NSTACK_BIND_FAIL); - continue; - } - - NSTACK_CAL_FUN (nstack_module_ops (modIdx), bind, (tfd, addr, addrlen), - tem); + UNLOCK_FOR_EP(lock_info); + return ret_fd; +} - if (ns_success == tem) - { - fdInf->ops = nstack_module_ops (modIdx); - nstack_set_router_protocol (fdInf, modIdx); - nstack_set_routed_fd (fdInf, tfd); - retval = ns_success; - nstack_set_bind_ret (fdInf, modIdx, NSTACK_BIND_SUCCESS); - } - else - { - NSSOC_LOGWAR ("bind fail]module=%s,fd=%d", - nstack_get_module_name_by_idx (modIdx), tfd); - nstack_set_bind_ret (fdInf, modIdx, NSTACK_BIND_FAIL); - } - } +int nstack_get_stackid_by_name(char *stackname, int *stackid) +{ + int modIdx = 0; - if (-1 == selectmod) + nstack_each_mod_inx(modIdx) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("failed for no module selected]fd=%d", fd); + /* params are not NULL */ + if (strcmp(nstack_get_module_name_by_idx(modIdx), stackname) == 0) + { + *stackid = modIdx; + return ns_success; + } } + return ns_fail; +} -bind_over: - if (ns_success == retval) +int nstack_get_stackid_by_opt(nstack_fd_Inf * fdInf, int *stackid) +{ + *stackid = (int) fdInf->rd_opt; + switch (fdInf->rd_opt) { - fdInf->isBound = 1; + case NSTACK_RD_OPT_KERNEL: + *stackid = nstack_get_linux_mid(); + return ns_success; + + case NSTACK_RD_OPT_STACKPOOL: + return nstack_get_stackid_by_name(RD_STACKPOOL_NAME, stackid); + + default: + return ns_fail; } - NSSOC_LOGINF ("appfd=%d,prot_fd=%d,rmidx=%d, retVal=%d [return]", fd, - fdInf->rlfd, fdInf->rmidx, retval); - UNLOCK_COMMON (fd, local_lock); - return retval; } -int -nstack_listen (int fd, int backlog) +int nstack_socket_get_stackid(nstack_fd_Inf * fdInf, + const struct sockaddr *addr, socklen_t addrlen) { - nstack_fd_Inf *fdInf; - int retval = -1; - int tem = -1; - int modIdx = 0; - int tfd; - int func_called = 0; - - NSTACK_INIT_CHECK_RET (listen, fd, backlog); - - NSSOC_LOGINF ("(sockfd=%d, backlog=%d) [Caller]", fd, backlog); - if (fd < 0) - { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d,backlog=%d [return]", fd, backlog); - return -1; - } - - NSTACK_FD_LINUX_CHECK (fd, listen, fdInf, (fd, backlog)); - - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON (fd, listen, fdInf, ENOTSOCK, - local_lock); - - /*listen:use all mode we support */ - nstack_each_modInx (modIdx) - { - tfd = nstack_get_protoFd (fdInf, modIdx); - - if ((-1 == tfd) - || (NSTACK_BIND_FAIL == nstack_get_bind_ret (fdInf, modIdx))) - { - continue; - } - - func_called = 1; - NSTACK_CAL_FUN (nstack_module_ops (modIdx), listen, (tfd, backlog), tem); - if (ns_success == tem) - { - nstack_set_listen_state (fdInf, modIdx, NSTACK_LISTENING); - NSTACK_SET_FD_LISTEN_SOCKET (fdInf); - retval = ns_success; - nstack_set_listen_ret (fdInf, modIdx, NSTACK_LISTEN_SUCCESS); - } + + nstack_rd_key rdkey = { 0 }; + + if (fdInf->rd_opt != -1) + { + return nstack_get_stackid_by_opt(fdInf, &fdInf->rd_item.stack_id); + } + + if (addr->sa_family == AF_INET) + { + rdkey.type = RD_DATA_TYPE_IP; + rdkey.ip_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; + } + else if (addr->sa_family == AF_INET6) + { + rdkey.type = RD_DATA_TYPE_IP6; + rdkey.in6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr; + } else - { - NSSOC_LOGWAR ("listen fail]fd=%d,module=%s,tfd=%d", fd, - nstack_get_module_name_by_idx (modIdx), tfd); - nstack_set_listen_ret (fdInf, modIdx, NSTACK_LISTEN_FAIL); - nstack_set_listen_state (fdInf, modIdx, NSTACK_NO_LISTENING); - } - } + { + rdkey.type = RD_DATA_TYPE_MAX; + } - if (0 == func_called) + if (rdkey.type == RD_DATA_TYPE_MAX) { - retval = -1; - nstack_set_errno (ENOSYS); - NSSOC_LOGERR ("listen fail for no module called]fd=%d", fd); + fdInf->rd_item.stack_id = nstack_get_linux_mid(); + return ns_success; } - NSSOC_LOGINF ("fd=%d,ret=%d [return]", fd, retval); - UNLOCK_COMMON (fd, local_lock); - return retval; + return nstack_rd_get_stackid(&rdkey, &fdInf->rd_item); } -int -nstack_accept (int fd, struct sockaddr *addr, socklen_t * addr_len) +int nstack_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { - nstack_fd_Inf *apstfdInf = NULL; - int tfd = -1; - int accfd = -1; - int fix_fd; - int ret_fd = -1; - nstack_fd_Inf *accInf; - int ret = -1; + nstack_fd_Inf *fdInf; + int retval = ns_fail; + int tem = -1; + int modIdx = 0; + int tfd; + nstack_rd_key rdkey = { 0 }; - NSTACK_INIT_CHECK_RET (accept, fd, addr, addr_len); + NSTACK_INIT_CHECK_RET(bind, fd, addr, addrlen); - NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, - addr_len); - if (fd < 0) + NSSOC_LOGINF("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, + addrlen); + + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("fd is invalid]fd=%d [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d,addr=%p,len=0x%x [return]", fd, + addr, addrlen); + return -1; + } + if ((NULL == addr) || (addrlen < 2)) + { + nstack_set_errno(EINVAL); + NSSOC_LOGERR("invalid input]fd=%d,addr=%p,len=0x%x [return]", fd, + addr, addrlen); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, accept, apstfdInf, (fd, addr, addr_len)); - nstack_fd_local_lock_info_t *local_lock = &apstfdInf->local_lock; - LOCK_ACCEPT (fd, apstfdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_ACCEPT (fd, accept, apstfdInf, ENOTSOCK, - local_lock); + /*avoid access to iaddr memory */ + /*miss the condition about sockaddr_un,and get wrong value */ + if ((addrlen >= sizeof(struct sockaddr_in)) + && ((addr->sa_family) == AF_INET)) + { + struct sockaddr_in *iaddr = (struct sockaddr_in *) addr; + NSSOC_LOGINF("fd=%d,addr=*.*.%u.%u,port=%d", fd, + FUZZY_IP_VAR(&iaddr->sin_addr), ntohs(iaddr->sin_port)); + } + else if ((addrlen >= sizeof(struct sockaddr_in6)) + && ((addr->sa_family) == AF_INET6)) + { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr; + NSSOC_LOGINF("fd=%d,addr=%s,port=%u", fd, + inet6_ntoa(&addr6->sin6_addr), htons(addr6->sin6_port)); + } + else + { + NSSOC_LOGINF("addrlen = %d ,fd=%d", (int) addrlen, fd); + } - if (addr) + NSTACK_FD_LINUX_CHECK_RETURN(fd, bind, fdInf, (fd, addr, addrlen)); + + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); + + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON(fd, bind, fdInf, ENOTSOCK, + local_lock); + + /*bind repeat, first time success, other return fail */ + if (fdInf->isBound) { - if ((!addr_len) || (*addr_len == NSTACK_MAX_U32_NUM)) - { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("addr_len input error [return]"); - UNLOCK_ACCEPT (fd, local_lock); - return -1; - } + nstack_set_errno(EINVAL); + NSPOL_LOGERR("error, alread bind]fd=%d", fd); + UNLOCK_COMMON(fd, fdInf, local_lock); + return -1; } - /*if no module select or listen / bind fail, just return fail */ - if ((!apstfdInf->ops) - || (NSTACK_LISTEN_FAIL == - nstack_get_listen_ret (apstfdInf, apstfdInf->rmidx)) - || (NSTACK_BIND_FAIL == - nstack_get_bind_ret (apstfdInf, apstfdInf->rmidx))) + /*just support af_inet and pf_inet */ + if (addr->sa_family != AF_INET && addr->sa_family != PF_INET + && addr->sa_family != AF_INET6) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR - ("nstack accept fd=%d no module select, or bind/listen fail [return]", - fd); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + nstack_set_errno(EAFNOSUPPORT); + NSSOC_LOGERR("not surport]fd=%d,domain=%d,[return]", fd, + addr->sa_family); + UNLOCK_COMMON(fd, fdInf, local_lock); + return -1; } - tfd = nstack_get_protoFd (apstfdInf, apstfdInf->rmidx); - NSTACK_CAL_FUN (nstack_module_ops (apstfdInf->rmidx), accept, - (tfd, addr, addr_len), accfd); - NSSOC_LOGINF ("nstack fd=%d:%d accept fd=%d from module=%s", fd, tfd, accfd, - nstack_get_module_name_by_idx (apstfdInf->rmidx)); - if (-1 == accfd) + + /* need check addrlen's validity, will visite iaddr->sin_addr.s_addr following code + for visite iaddr->sin_addr.s_addr is 8 byte */ + if (addrlen < 8) { - if (errno != EAGAIN) + nstack_set_errno(EINVAL); + NSPOL_LOGERR("addrlen<sizeof(struct sockaddr_in)]addrlen=%u", + addrlen); + UNLOCK_COMMON(fd, fdInf, local_lock); + return -1; + } + + /* for custom socket, choose stack after creating socket. */ + if (fdInf->ops) + { + NSTACK_CAL_FUN(fdInf->ops, bind, (fdInf->rlfd, addr, addrlen), tem); + if (ns_success == tem) + { + retval = ns_success; + nstack_set_bind_ret(fdInf, fdInf->rmidx, NSTACK_BIND_SUCCESS); + } + else { - NSSOC_LOGERR ("appfd=%d,module=%s,ret=%d,errno=%d [return]", fd, - nstack_get_module_name_by_idx (apstfdInf->rmidx), - accfd, errno); + nstack_set_bind_ret(fdInf, fdInf->rmidx, NSTACK_BIND_FAIL); } - UNLOCK_ACCEPT (fd, local_lock); - return -1; + goto bind_over; } - // If it is not from kernel, need to create one kernel socket - if (apstfdInf->rmidx != nstack_get_fix_mid ()) + if (fdInf->rd_opt != -1) { - /*err num is same with linux */ - fix_fd = nstack_extern_deal (nstack_get_fix_mid ()).stack_alloc_fd (); - if (fix_fd < 0) + retval = nstack_get_stackid_by_opt(fdInf, &fdInf->rd_item.stack_id); + if (ns_success != retval) + { + NSSOC_LOGWAR + ("fd Can't select any module by opt for]fd=%d,opt=%d", fd, + fdInf->rd_opt); + fdInf->rd_item.stack_id = -1; + } + else { - NSSOC_LOGERR - ("nstack accept fd=%d return fd=%d kernelFD fd create fail [return]", - fd, accfd); - NSTACK_CAL_FUN (nstack_module_ops (apstfdInf->rmidx), close, - (accfd), ret); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + NSSOC_LOGINF("fd opt Select module]fd=%d,opt=%d,module=%s", + fd, fdInf->rd_opt, + nstack_get_module_name_by_idx(fdInf-> + rd_item.stack_id)); } } - else + else { - fix_fd = accfd; + if (addr->sa_family == AF_INET) + { + struct sockaddr_in *iaddr = (struct sockaddr_in *) addr; + /*loop ip call linux */ + if (NSTACK_LOOP_IP == iaddr->sin_addr.s_addr) + { + fdInf->rd_item.stack_id = nstack_get_linux_mid(); + } + /*any ip call defaul mod */ + else if (NSTACK_ANY_IP == iaddr->sin_addr.s_addr) + { + fdInf->rd_item.stack_id = nstack_defmod_inx(); + } + else + { + rdkey.type = RD_DATA_TYPE_IP; + rdkey.ip_addr = iaddr->sin_addr.s_addr; + retval = nstack_rd_get_stackid(&rdkey, &fdInf->rd_item); + if (ns_success != retval) + { + NSSOC_LOGWAR + ("fd Can't select any module for]fd=%d,IP=*.*.%u.%u", + fd, FUZZY_IP_VAR(&iaddr->sin_addr)); + } + else + { + NSSOC_LOGINF + ("fd addr Select module]fd=%d,addr=*.*.%u.%u,module=%s", + fd, FUZZY_IP_VAR(&iaddr->sin_addr), + nstack_get_module_name_by_idx(fdInf-> + rd_item.stack_id)); + } + } + } + else if (addr->sa_family == AF_INET6) + { + struct in6_addr *in6 = &((struct sockaddr_in6 *) addr)->sin6_addr; + + /*loop ip call linux */ + if (IN6_IS_ADDR_LOOPBACK(in6)) + { + fdInf->rd_item.stack_id = nstack_get_linux_mid(); + } + /*any ip call defaul mod */ + else if (IN6_IS_ADDR_UNSPECIFIED(in6)) + { + fdInf->rd_item.stack_id = nstack_get_linux_mid(); + } + else + { + rdkey.type = RD_DATA_TYPE_IP6; + rdkey.in6_addr = *in6; + retval = nstack_rd_get_stackid(&rdkey, &fdInf->rd_item); + if (ns_success != retval) + { + NSSOC_LOGWAR + ("fd Can't select any module for]fd=%d,IP==%s", fd, + inet6_ntoa(in6)); + } + else + { + NSSOC_LOGINF + ("fd addr Select module]fd=%d,addr=%s,module=%s", fd, + inet6_ntoa(in6), + nstack_get_module_name_by_idx(fdInf-> + rd_item.stack_id)); + } + } + } + else + { + fdInf->rd_item.stack_id = nstack_get_linux_mid(); + } } - if (fix_fd >= (int) NSTACK_KERNEL_FD_MAX) + retval = -1; + nstack_each_mod_inx(modIdx) { - /* nstack not support kernel fd >= NSTACK_MAX_SOCK_NUM. - * close it and nstack_accept() return failed - */ - NSSOC_LOGERR ("kernelFD fd too big, close it. kernelFD=%d [return]", - accfd); - NSTACK_CAL_FUN (nstack_module_ops (apstfdInf->rmidx), close, (accfd), - ret); - if (apstfdInf->rmidx != nstack_get_fix_mid ()) + tfd = nstack_get_proto_fd(fdInf, modIdx); + if ((-1 == tfd) || (fdInf->rd_item.stack_id != modIdx)) // for INADDR_ANY, need try to bind on both lwip and linux + { + /*tfd is -1, but is the select module */ + if (fdInf->rd_item.stack_id == modIdx) + { + retval = -1; + nstack_set_errno(ENOSYS); + NSSOC_LOGDBG + ("fd tfd=-1, but is the select module]fd=%d,tfd=-1,modIdx=%d", + fd, modIdx); + } + nstack_set_bind_ret(fdInf, modIdx, NSTACK_BIND_FAIL); + continue; + } + + NSTACK_CAL_FUN(nstack_module_ops(modIdx), bind, + (tfd, addr, addrlen), tem); + + if (ns_success == tem) + { + fdInf->ops = nstack_module_ops(modIdx); + nstack_set_router_protocol(fdInf, modIdx); /*do not need return value */ + nstack_set_routed_fd(fdInf, tfd); /*do not need return value */ + retval = ns_success; + nstack_set_bind_ret(fdInf, modIdx, NSTACK_BIND_SUCCESS); + } + else { - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (fix_fd), ret); + NSSOC_LOGWAR("bind fail]module=%s,fd=%d", + nstack_get_module_name_by_idx(modIdx), tfd); + nstack_set_bind_ret(fdInf, modIdx, NSTACK_BIND_FAIL); } - nstack_set_errno (EMFILE); - UNLOCK_ACCEPT (fd, local_lock); - return -1; } - nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info (fix_fd); - LOCK_FOR_EP (lock_info); + if (-1 == fdInf->rd_item.stack_id) + { + nstack_set_errno(EINVAL); + NSSOC_LOGERR("failed for no module selected]fd=%d", fd); + } - accInf = nstack_lk_fd_alloc_with_kernel (fix_fd); - ret_fd = fix_fd; + bind_over: + if (ns_success == retval) + { + fdInf->isBound = 1; + } + NSSOC_LOGINF("appfd=%d,prot_fd=%d,rmidx=%d, retVal=%d [return]", fd, + fdInf->rlfd, fdInf->rmidx, retval); + UNLOCK_COMMON(fd, fdInf, local_lock); + return retval; +} - if (NULL == accInf) +int nstack_listen(int fd, int backlog) +{ + nstack_fd_Inf *fdInf; + int retval = -1; + int tem = -1; + int modIdx = 0; + int tfd; + int func_called = 0; + + NSTACK_INIT_CHECK_RET(listen, fd, backlog); + + NSSOC_LOGINF("(sockfd=%d, backlog=%d) [Caller]", fd, backlog); + if (fd < 0) { - NSSOC_LOGERR ("Can't alloc nstack fdInf [return]"); - NSTACK_CAL_FUN (nstack_module_ops (apstfdInf->rmidx), close, (accfd), - ret); - if (apstfdInf->rmidx != nstack_get_fix_mid ()) + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d,backlog=%d [return]", fd, backlog); + return -1; + } + + NSTACK_FD_LINUX_CHECK_RETURN(fd, listen, fdInf, (fd, backlog)); + + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); + + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON(fd, listen, fdInf, ENOTSOCK, + local_lock); + + /*listen:use all mode we support */ + nstack_each_mod_inx(modIdx) + { + tfd = nstack_get_proto_fd(fdInf, modIdx); + + if ((-1 == tfd) + || (NSTACK_BIND_FAIL == nstack_get_bind_ret(fdInf, modIdx))) { - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (fix_fd), ret); + continue; } - UNLOCK_FOR_EP (lock_info); - nstack_set_errno (EMFILE); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + func_called = 1; + NSTACK_CAL_FUN(nstack_module_ops(modIdx), listen, (tfd, backlog), + tem); + if (ns_success == tem) + { + nstack_set_listen_state(fdInf, modIdx, NSTACK_LISENING); + NSTACK_SET_FD_LISTEN_SOCKET(fdInf); + retval = ns_success; + nstack_set_listen_ret(fdInf, modIdx, NSTACK_LISTEN_SUCCESS); + } + else + { + NSSOC_LOGWAR("listen fail]fd=%d,module=%s,tfd=%d", fd, + nstack_get_module_name_by_idx(modIdx), tfd); + nstack_set_listen_ret(fdInf, modIdx, NSTACK_LISTEN_FAIL); + nstack_set_listen_state(fdInf, modIdx, NSTACK_NO_LISENING); + } } - nstack_set_routed_fd (accInf, accfd); - accInf->ops = nstack_module_ops (apstfdInf->rmidx); - /*do not include SOCK_CLOEXEC SOCK_NONBLOCK */ - accInf->type = - apstfdInf->type & (~((ns_int32) SOCK_CLOEXEC | (ns_int32) SOCK_NONBLOCK)); - nstack_set_router_protocol (accInf, apstfdInf->rmidx); - nstack_set_protoFd (accInf, apstfdInf->rmidx, accfd); - nstack_set_app_info (accInf, apstfdInf->rmidx); - /* Set the linux kernel fd also in accInf for kernel module (0) */ - if (apstfdInf->rmidx != nstack_get_fix_mid ()) + if (0 == func_called) { - nstack_set_protoFd (accInf, nstack_get_fix_mid (), fix_fd); + retval = -1; + nstack_set_errno(ENOSYS); + NSSOC_LOGERR("listen fail for no module called]fd=%d", fd); } - NSSOC_LOGINF ("listenfd=%d,acceptfd=%d,module=%s(rlfd=%d),ret=%d [return]", - fd, ret_fd, nstack_get_module_name_by_idx (apstfdInf->rmidx), - accfd, ret_fd); - set_fd_status_lock_fork (ret_fd, FD_OPEN); - UNLOCK_FOR_EP (lock_info); - UNLOCK_ACCEPT (fd, local_lock); - return ret_fd; + NSSOC_LOGINF("fd=%d,ret=%d [return]", fd, retval); + UNLOCK_COMMON(fd, fdInf, local_lock); + return retval; } -int -nstack_accept4 (int fd, struct sockaddr *addr, - socklen_t * addr_len, int flags) +int nstack_accept(int fd, struct sockaddr *addr, socklen_t * addr_len) { - nstack_fd_Inf *pstfdInf = NULL; - int tfd = -1; - int accfd = -1; - int fix_fd = -1; - int ret_fd = -1; - int ret = -1; - nstack_fd_Inf *accInf; + nstack_fd_Inf *apstfdInf = NULL; + int tfd = -1; + int accfd = -1; +#ifdef KERNEL_FD_SUPPORT + int kernelFD; +#endif + int ret_fd = -1; + nstack_fd_Inf *accInf; + int ret = -1; - NSTACK_INIT_CHECK_RET (accept4, fd, addr, addr_len, flags); + NSTACK_INIT_CHECK_RET(accept, fd, addr, addr_len); - NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%p, flags=%d) [Caller]", fd, - addr, addr_len, flags); - if (fd < 0) + NSSOC_LOGINF("(sockfd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, + addr_len); + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("nstack accept4,fd=%d invalid [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("fd is invalid]fd=%d [return]", fd); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, accept4, pstfdInf, (fd, addr, addr_len, flags)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, accept, apstfdInf, (fd, addr, addr_len)); - nstack_fd_local_lock_info_t *local_lock = &pstfdInf->local_lock; - LOCK_ACCEPT (fd, pstfdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_ACCEPT (fd, accept4, pstfdInf, ENOTSOCK, - local_lock); + nstack_fd_local_lock_info_t *local_lock = &apstfdInf->local_lock; + LOCK_ACCEPT(fd, apstfdInf, local_lock); - if (addr) + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_ACCEPT(fd, accept, apstfdInf, ENOTSOCK, + local_lock); + + if (addr) { - if ((!addr_len) || (*addr_len == NSTACK_MAX_U32_NUM)) + if ((!addr_len) || (*addr_len == NSTACK_MAX_U32_NUM)) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("nstack accept4 addr_len input error [return]"); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + nstack_set_errno(EINVAL); + NSSOC_LOGERR("addr_len inpurt error [return]"); + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + return -1; } } - /*if no module select or listen / bind fail, just return fail */ - if ((!pstfdInf->ops) - || (NSTACK_LISTEN_FAIL == - nstack_get_listen_ret (pstfdInf, pstfdInf->rmidx)) - || (NSTACK_BIND_FAIL == - nstack_get_bind_ret (pstfdInf, pstfdInf->rmidx))) + /*if no module select or listen / bind fail, just return fail */ + if ((!apstfdInf->ops) + || (NSTACK_LISTEN_FAIL == + nstack_get_listen_ret(apstfdInf, apstfdInf->rmidx)) + || (NSTACK_BIND_FAIL == + nstack_get_bind_ret(apstfdInf, apstfdInf->rmidx))) + { + nstack_set_errno(EINVAL); + NSSOC_LOGERR + ("nstack accept fd=%d no mudle select, or bind/listen fail [return]", + fd); + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + return -1; + } + tfd = nstack_get_proto_fd(apstfdInf, apstfdInf->rmidx); + NSTACK_CAL_FUN(nstack_module_ops(apstfdInf->rmidx), accept, + (tfd, addr, addr_len), accfd); + NSSOC_LOGINF("nstack fd=%d:%d accept fd=%d from module=%s", fd, tfd, + accfd, nstack_get_module_name_by_idx(apstfdInf->rmidx)); + if (-1 == accfd) + { + if (errno != EAGAIN) + { + NSSOC_LOGERR("appfd=%d,module=%s,ret=%d,errno=%d [return]", fd, + nstack_get_module_name_by_idx(apstfdInf->rmidx), + accfd, errno); + } + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + return -1; + } + +#ifdef KERNEL_FD_SUPPORT + // If it is not from kernel, need to create one kernel socket + if (apstfdInf->rmidx != nstack_get_linux_mid()) + { + /*err num is same with linux */ + kernelFD = nstack_create_kernel_socket(); + if (kernelFD < 0) + { + NSSOC_LOGERR + ("nstack accept fd=%d return fd=%d kernelFD fd create fail [return]", + fd, accfd); + NSTACK_CAL_FUN(nstack_module_ops(apstfdInf->rmidx), close, + (accfd), ret); + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + return -1; + } + } + else { - nstack_set_errno (EINVAL); - NSSOC_LOGERR - ("nstack accept4 fd:%d no module select, or bind/listen fail [return]", - fd); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + kernelFD = accfd; } - tfd = nstack_get_protoFd (pstfdInf, pstfdInf->rmidx); - NSTACK_CAL_FUN (nstack_module_ops (pstfdInf->rmidx), accept4, - (tfd, addr, addr_len, flags), accfd); - if (-1 == accfd) + if (kernelFD >= (int) NSTACK_KERNEL_FD_MAX) { - if (errno != EAGAIN) + /* nstack not support kernel fd >= NSTACK_MAX_SOCK_NUM. + * close it and nstack_accept() return failed + */ + NSSOC_LOGERR("kernelFD fd too big, close it. kernelFD=%d [return]", + accfd); + + NSTACK_CAL_FUN(nstack_module_ops(apstfdInf->rmidx), close, (accfd), + ret); + if (apstfdInf->rmidx != nstack_get_linux_mid()) { - NSSOC_LOGERR ("appfd=%d,module=%s,ret=%d,errno=%d [return]", fd, - nstack_get_module_name_by_idx (pstfdInf->rmidx), - accfd, errno); + + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), + close, (kernelFD), ret); } - UNLOCK_ACCEPT (fd, local_lock); - return -1; + nstack_set_errno(EMFILE); + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + return -1; } - // If it is not from kernel, need to create one kernel socket - if (pstfdInf->rmidx != nstack_get_fix_mid ()) + nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info(kernelFD); + LOCK_FOR_EP(lock_info); + + accInf = nstack_lk_fd_alloc_with_kernel(kernelFD); + ret_fd = kernelFD; +#else + accInf = nstack_lk_fd_alloc_without_kernel(); +#endif + + if (NULL == accInf) { - fix_fd = nstack_extern_deal (nstack_get_fix_mid ()).stack_alloc_fd (); + NSSOC_LOGERR("Can't alloc nstack fdInf [return]"); + + NSTACK_CAL_FUN(nstack_module_ops(apstfdInf->rmidx), close, (accfd), + ret); +#ifdef KERNEL_FD_SUPPORT + if (apstfdInf->rmidx != nstack_get_linux_mid()) + { + + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), + close, (kernelFD), ret); + } + UNLOCK_FOR_EP(lock_info); +#endif + nstack_set_errno(EMFILE); + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + + return -1; + } + +#ifndef KERNEL_FD_SUPPORT + nstack_fd_local_lock_info_t *lock_info = + get_fd_local_lock_info(accInf->fd); + ret_fd = accInf->fd; + LOCK_FOR_EP(lock_info); +#endif + + nstack_set_routed_fd(accInf, accfd); /*do not need return value */ + accInf->ops = nstack_module_ops(apstfdInf->rmidx); + /*donot include SOCK_CLOEXEC SOCK_NONBLOCK */ + accInf->type = + apstfdInf->type & + (~((ns_int32) SOCK_CLOEXEC | (ns_int32) SOCK_NONBLOCK)); + nstack_set_router_protocol(accInf, apstfdInf->rmidx); /*do not need return value */ + nstack_set_proto_fd(accInf, apstfdInf->rmidx, accfd); + nstack_set_app_info(accInf, apstfdInf->rmidx); + /* Set the linux kernel fd also in accInf for kernel module (0) */ +#ifdef KERNEL_FD_SUPPORT + if (apstfdInf->rmidx != nstack_get_linux_mid()) + { + nstack_set_proto_fd(accInf, nstack_get_linux_mid(), kernelFD); } - else +#endif + NSSOC_LOGINF + ("listenfd=%d,acceptfd=%d,module=%s(rlfd=%d),ret=%d [return]", fd, + ret_fd, nstack_get_module_name_by_idx(apstfdInf->rmidx), accfd, + ret_fd); + + set_fd_status_lock_fork(ret_fd, FD_OPEN); + UNLOCK_FOR_EP(lock_info); + UNLOCK_ACCEPT(fd, apstfdInf, local_lock); + return ret_fd; +} + +int nstack_accept4(int fd, struct sockaddr *addr, + socklen_t * addr_len, int flags) +{ + nstack_fd_Inf *pstfdInf = NULL; + int tfd = -1; + int accfd = -1; +#ifdef KERNEL_FD_SUPPORT + int kernelFD = -1; +#endif + int ret_fd = -1; + int ret = -1; + nstack_fd_Inf *accInf; + + NSTACK_INIT_CHECK_RET(accept4, fd, addr, addr_len, flags); + + NSSOC_LOGINF("(sockfd=%d, addr=%p, addrlen=%p, flags=%d) [Caller]", fd, + addr, addr_len, flags); + if (fd < 0) { - fix_fd = accfd; + nstack_set_errno(EBADF); + NSSOC_LOGERR("nstack accept4,fd=%d invalid [return]", fd); + return -1; } + NSTACK_FD_LINUX_CHECK_RETURN(fd, accept4, pstfdInf, + (fd, addr, addr_len, flags)); + + nstack_fd_local_lock_info_t *local_lock = &pstfdInf->local_lock; + LOCK_ACCEPT(fd, pstfdInf, local_lock); + + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_ACCEPT(fd, accept4, pstfdInf, ENOTSOCK, + local_lock); - if (!nstack_is_nstack_sk (fix_fd)) + if (addr) { - /* nstack not support kernel fd >= NSTACK_MAX_SOCK_NUM. - * close it and nstack_accept() return failed - */ - NSSOC_LOGERR - ("nstack accept4 fd=%d kernelFD fd too big, close it. kernelFD=%d [return]", - fd, fix_fd); - if (fix_fd >= 0) + if ((!addr_len) || (*addr_len == NSTACK_MAX_U32_NUM)) { - NSTACK_CAL_FUN (nstack_module_ops (pstfdInf->rmidx), close, (accfd), - ret); + nstack_set_errno(EINVAL); + NSSOC_LOGERR("nstack accept4 addr_len inpurt error [return]"); + UNLOCK_ACCEPT(fd, pstfdInf, local_lock); + return -1; } + } - if (pstfdInf->rmidx != nstack_get_fix_mid ()) + /*if no module select or listen / bind fail, just return fail */ + if ((!pstfdInf->ops) + || (NSTACK_LISTEN_FAIL == + nstack_get_listen_ret(pstfdInf, pstfdInf->rmidx)) + || (NSTACK_BIND_FAIL == + nstack_get_bind_ret(pstfdInf, pstfdInf->rmidx))) + { + nstack_set_errno(EINVAL); + NSSOC_LOGERR + ("nstack accept4 fd:%d no mudle select, or bind/listen fail [return]", + fd); + UNLOCK_ACCEPT(fd, pstfdInf, local_lock); + return -1; + } + + tfd = nstack_get_proto_fd(pstfdInf, pstfdInf->rmidx); + NSTACK_CAL_FUN(nstack_module_ops(pstfdInf->rmidx), accept4, + (tfd, addr, addr_len, flags), accfd); + if (-1 == accfd) + { + if (errno != EAGAIN) { - NSTACK_CAL_FUN (nstack_module_ops (nstack_get_fix_mid ()), close, - (fix_fd), ret); + NSSOC_LOGERR("appfd=%d,module=%s,ret=%d,errno=%d [return]", fd, + nstack_get_module_name_by_idx(pstfdInf->rmidx), + accfd, errno); } - nstack_set_errno (EMFILE); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + UNLOCK_ACCEPT(fd, pstfdInf, local_lock); + return -1; } - nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info (fix_fd); - LOCK_FOR_EP (lock_info); - accInf = nstack_lk_fd_alloc_with_kernel (fix_fd); - ret_fd = fix_fd; +#ifdef KERNEL_FD_SUPPORT + // If it is not from kernel, need to create one kernel socket + if (pstfdInf->rmidx != nstack_get_linux_mid()) + kernelFD = nstack_create_kernel_socket(); + else + kernelFD = accfd; - if (NULL == accInf) + if (!nstack_is_nstack_sk(kernelFD)) { - NSTACK_CAL_FUN (nstack_module_ops (pstfdInf->rmidx), close, (accfd), - ret); - if (pstfdInf->rmidx != nstack_get_fix_mid ()) + /* nstack not support kernel fd >= NSTACK_MAX_SOCK_NUM. + * close it and nstack_accept() return failed + */ + NSSOC_LOGERR + ("nstack accept4 fd=%d kernelFD fd too big, close it. kernelFD=%d [return]", + fd, kernelFD); + + if (kernelFD >= 0) + NSTACK_CAL_FUN(nstack_module_ops(pstfdInf->rmidx), close, + (accfd), ret); + + if (pstfdInf->rmidx != nstack_get_linux_mid()) { - NSTACK_CAL_FUN (nstack_module_ops (nstack_get_fix_mid ()), close, - (fix_fd), ret); + + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), + close, (kernelFD), ret); } - UNLOCK_FOR_EP (lock_info); - NSSOC_LOGERR ("nstack accept fd alloc is NULL [return]"); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + nstack_set_errno(EMFILE); + UNLOCK_ACCEPT(fd, pstfdInf, local_lock); + return -1; } - nstack_set_routed_fd (accInf, accfd); - accInf->ops = nstack_module_ops (pstfdInf->rmidx); - accInf->type = - (pstfdInf->type & (~((ns_int32) SOCK_CLOEXEC | (ns_int32) SOCK_NONBLOCK))) - | (ns_int32) flags; - nstack_set_router_protocol (accInf, pstfdInf->rmidx); - nstack_set_protoFd (accInf, pstfdInf->rmidx, accfd); - nstack_set_app_info (accInf, pstfdInf->rmidx); - /* Set the linux kernel fd also in accInf for kernel module (0) */ - if (pstfdInf->rmidx != nstack_get_fix_mid ()) + nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info(kernelFD); + LOCK_FOR_EP(lock_info); + accInf = nstack_lk_fd_alloc_with_kernel(kernelFD); + ret_fd = kernelFD; +#else + accInf = nstack_lk_fd_alloc_without_kernel(); +#endif + + if (NULL == accInf) { - nstack_set_protoFd (accInf, nstack_get_fix_mid (), fix_fd); + + NSTACK_CAL_FUN(nstack_module_ops(pstfdInf->rmidx), close, (accfd), + ret); +#ifdef KERNEL_FD_SUPPORT + if (pstfdInf->rmidx != nstack_get_linux_mid()) + { + + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), + close, (kernelFD), ret); + } + UNLOCK_FOR_EP(lock_info); +#endif + NSSOC_LOGERR("nstack accept fd alloc is NULL [return]"); + UNLOCK_ACCEPT(fd, pstfdInf, local_lock); + return -1; } - NSSOC_LOGINF - ("listenfd=%d,acceptfd=%d,accInf->fd=%d,module=%s(rlfd:%d),ret=%d [return]", - fd, ret_fd, accInf->fd, nstack_get_module_name_by_idx (pstfdInf->rmidx), - accfd, ret_fd); - set_fd_status_lock_fork (ret_fd, FD_OPEN); - UNLOCK_FOR_EP (lock_info); - UNLOCK_ACCEPT (fd, local_lock); - return ret_fd; + +#ifndef KERNEL_FD_SUPPORT + nstack_fd_local_lock_info_t *lock_info = + get_fd_local_lock_info(accInf->fd); + ret_fd = accInf->fd; + LOCK_FOR_EP(lock_info); +#endif + + nstack_set_routed_fd(accInf, accfd); /*do not need return value */ + accInf->ops = nstack_module_ops(pstfdInf->rmidx); + accInf->type = + (pstfdInf->type & + (~((ns_int32) SOCK_CLOEXEC | (ns_int32) SOCK_NONBLOCK))) | (ns_int32) + flags; + nstack_set_router_protocol(accInf, pstfdInf->rmidx); /*do not need return value */ + nstack_set_proto_fd(accInf, pstfdInf->rmidx, accfd); + nstack_set_app_info(accInf, pstfdInf->rmidx); +#ifdef KERNEL_FD_SUPPORT + /* Set the linux kernel fd also in accInf for kernel module (0) */ + if (pstfdInf->rmidx != nstack_get_linux_mid()) + { + nstack_set_proto_fd(accInf, nstack_get_linux_mid(), kernelFD); + } +#endif + NSSOC_LOGINF + ("listenfd=%d,acceptfd=%d,accInf->fd=%d,module=%s(rlfd:%d),ret=%d [return]", + fd, ret_fd, accInf->fd, + nstack_get_module_name_by_idx(pstfdInf->rmidx), accfd, ret_fd); + set_fd_status_lock_fork(ret_fd, FD_OPEN); + UNLOCK_FOR_EP(lock_info); + UNLOCK_ACCEPT(fd, pstfdInf, local_lock); + return ret_fd; } -/***************************************************************** -Parameters : fd - addr - len -Return : -Description : use the rd select rlfd or default rlfd to Establish connection. the unused fd should closed -*****************************************************************/ -int -nstack_connect (int fd, const struct sockaddr *addr, socklen_t addrlen) +int nstack_connect(int fd, const struct sockaddr *addr, socklen_t addrlen) { - int retval = -1; - nstack_fd_Inf *fdInf; - struct sockaddr_in *iaddr = NULL; - iaddr = (struct sockaddr_in *) addr; - int selectmod = -1; - nstack_rd_key rdkey = { 0 }; + int retval = -1; + nstack_fd_Inf *fdInf; + struct sockaddr_in *iaddr = (struct sockaddr_in *) addr; - NSTACK_INIT_CHECK_RET (connect, fd, addr, addrlen); + NSTACK_INIT_CHECK_RET(connect, fd, addr, addrlen); - NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, - addrlen); + NSSOC_LOGINF("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, + addrlen); - if (fd < 0) + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR - ("nstack connect, fd=%d invalid input: addr=%p,len=0x%x [return]", fd, - addr, addrlen); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR + ("nstack connect, fd=%d invalid input: addr=%p,len=0x%x [return]", + fd, addr, addrlen); + return -1; } - if ((NULL == addr) || (addrlen < 2)) + if ((NULL == addr) || (addrlen < 2)) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR - ("nstack connect, fd=%d invalid input: addr=%p,len=0x%x [return]", fd, - addr, addrlen); - return -1; + nstack_set_errno(EINVAL); + NSSOC_LOGERR + ("nstack connect, fd=%d invalid input: addr=%p,len=0x%x [return]", + fd, addr, addrlen); + return -1; } - if ((addrlen >= sizeof (struct sockaddr_in)) - && ((addr->sa_family) == AF_INET)) + /* avoid access to iaddr memory */ + /* miss the condition about sockaddr_un,and get wrong value */ + if ((addrlen >= sizeof(struct sockaddr_in)) + && ((addr->sa_family) == AF_INET)) { - NSSOC_LOGINF ("fd=%d,addr=%s,port=%d", fd, inet_ntoa (iaddr->sin_addr), - ntohs (iaddr->sin_port)); + NSSOC_LOGINF("fd=%d,addr=*.*.%u.%u,port=%d", fd, + FUZZY_IP_VAR(&iaddr->sin_addr), ntohs(iaddr->sin_port)); } - else + else if ((addrlen >= sizeof(struct sockaddr_in6)) + && ((addr->sa_family) == AF_INET6)) { - NSSOC_LOGINF ("addrlen = %d ,fd=%d", (int) addrlen, fd); + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr; + NSSOC_LOGINF("fd=%d,addr=%s,port=%u", fd, + inet6_ntoa(&addr6->sin6_addr), htons(addr6->sin6_port)); + } + else + { + NSSOC_LOGINF("addrlen = %d ,fd=%d", (int) addrlen, fd); } - /* need check addrlen's validity, will visite iaddr->sin_addr.s_addr following code,for visite iaddr->sin_addr.s_addr is 8 byte */ - if (addrlen < 8) + /* need check addrlen's validity, will visite iaddr->sin_addr.s_addr following code,for visite iaddr->sin_addr.s_addr is 8 byte */ + if (addrlen < 8) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR - ("nstack connect, fd=%d invalid addrlen input: addr=%p,len=0x%x [return]", - fd, addr, addrlen); - return -1; + nstack_set_errno(EINVAL); + NSSOC_LOGERR + ("nstack connect, fd=%d invalid addrlen input: addr=%p,len=0x%x [return]", + fd, addr, addrlen); + return -1; } - if (NSTACK_ANY_IP == iaddr->sin_addr.s_addr) + if (addr->sa_family == AF_INET) { - nstack_set_errno (ECONNREFUSED); - NSSOC_LOGERR - ("nstack connect, fd=%d invalid input: 0==addr_in->sin_addr.s_addr [return]", - fd); - return -1; + if (addrlen < sizeof(struct sockaddr_in)) + { + /* sa family is always AF_INET */ + NSSOC_LOGERR + ("nstack connect, fd=%d family=AF_INET invalid size: %d [return]", + fd, addrlen); + nstack_set_errno(EINVAL); + return -1; + } + if (NSTACK_ANY_IP == iaddr->sin_addr.s_addr) /*no need to check null pointer */ + { + nstack_set_errno(ECONNREFUSED); + NSSOC_LOGERR + ("nstack connect, fd=%d invalid input: 0==addr_in->sin_addr.s_addr [return]", + fd); + return -1; + } + else if (NSTACK_MAX_U32_NUM == iaddr->sin_addr.s_addr) /*no need to check null pointer */ + { + nstack_set_errno(ENETUNREACH); + NSSOC_LOGERR + ("nstack connect, fd=%d invalid input: 0xffffffff==addr_in->sin_addr.s_addr [return]", + fd); + return -1; + } } - else if (NSTACK_MAX_U32_NUM == iaddr->sin_addr.s_addr) + else if (addr->sa_family == AF_INET6) { - nstack_set_errno (ENETUNREACH); - NSSOC_LOGERR - ("nstack connect, fd=%d invalid input: 0xffffffff==addr_in->sin_addr.s_addr [return]", - fd); - return -1; + if (addrlen < sizeof(struct sockaddr_in6)) + { + NSSOC_LOGERR + ("nstack connect, fd=%d family=AF_INET6 invalid size: %d [return]", + fd, addrlen); + nstack_set_errno(EINVAL); + return -1; + } + + if (IN6_IS_ADDR_UNSPECIFIED + (&((const struct sockaddr_in6 *) addr)->sin6_addr)) + { + nstack_set_errno(ECONNREFUSED); + NSSOC_LOGERR + ("nstack connect, fd=%d invalid input: 0==addr_in->sin6_addr [return]", + fd); + return -1; + } } - NSTACK_FD_LINUX_CHECK (fd, connect, fdInf, (fd, addr, addrlen)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_CONNECT (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_CONNECT (fd, connect, fdInf, ENOTSOCK, - local_lock); + NSTACK_FD_LINUX_CHECK_RETURN(fd, connect, fdInf, (fd, addr, addrlen)); + + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_CONNECT(fd, fdInf, local_lock); - /*if no module select, according to dest ip */ - if (!fdInf->ops) + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_CONNECT(fd, connect, fdInf, ENOTSOCK, local_lock); /*do not need return value */ + + /*if no module select, according to dest ip */ + if (!fdInf->ops) { - rdkey.type = RD_DATA_TYPE_IP; - rdkey.ip_addr = iaddr->sin_addr.s_addr; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod == -1)) + retval = nstack_socket_get_stackid(fdInf, addr, addrlen); + if (ns_success == retval && fdInf->rd_item.stack_id != -1) { - rdkey.type = RD_DATA_TYPE_PROTO; - rdkey.proto_type = fdInf->type; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod < 0) - || (selectmod >= nstack_get_modNum ())) - { - NSSOC_LOGINF ("fd=%d addr=%s Select module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - selectmod = -1; - } - else - { - NSSOC_LOGINF ("Connect socket of]select modName=%s", - nstack_get_module_name_by_idx (selectmod)); - } + NSSOC_LOGINF("fd=%d addr=%s Select module=%s, rd_opt=%d", fd, + inet_ntoa_x(addr), + nstack_get_module_name_by_idx(fdInf-> + rd_item.stack_id), + fdInf->rd_opt); + /*in case of that multi-thread connect. if route was chosed by one thread, the other just use the first one */ + fdInf->rmidx = fdInf->rd_item.stack_id; + fdInf->ops = nstack_module_ops(fdInf->rd_item.stack_id); + nstack_set_routed_fd(fdInf, nstack_get_proto_fd(fdInf, fdInf->rd_item.stack_id)); /*do not need return value */ + nstack_set_router_protocol(fdInf, fdInf->rd_item.stack_id); /*do not need return value */ } - if (ns_success == retval && selectmod >= 0) + else { - NSSOC_LOGINF ("fd=%d addr=%s Select module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - /*in case of that multi-thread connect. if route was chosen by one thread, the other just use the first one */ - fdInf->rmidx = selectmod; - fdInf->ops = nstack_module_ops (selectmod); - nstack_set_routed_fd (fdInf, nstack_get_protoFd (fdInf, selectmod)); - nstack_set_router_protocol (fdInf, selectmod); + NSSOC_LOGERR + ("fd=%d Callback select module=%d rd_opt=%d, ret=0x%x", fd, + fdInf->rd_item.stack_id, fdInf->rd_opt, retval); + nstack_set_errno(ENETUNREACH); + UNLOCK_CONNECT(fd, fdInf, local_lock); + return -1; } - else - { - NSSOC_LOGERR ("fd=%d Callback select module=%d ret=0x%x", fd, - selectmod, retval); - nstack_set_errno (ENETUNREACH); - UNLOCK_CONNECT (fd, local_lock); - return -1; - } - NSSOC_LOGINF ("fd=%d addr=%s Select module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); } - NSTACK_CAL_FUN (fdInf->ops, connect, (fdInf->rlfd, addr, addrlen), retval); - if (-1 == retval && errno != EINPROGRESS) + NSTACK_CAL_FUN(fdInf->ops, connect, (fdInf->rlfd, addr, addrlen), retval); + if (-1 == retval && errno != EINPROGRESS) { - NSSOC_LOGERR ("appfd=%d,module=%s,proto_fd=%d,ret=%d,errno=%d [return]", - fd, nstack_get_module_name_by_idx (fdInf->rmidx), - fdInf->rlfd, retval, errno); + NSSOC_LOGERR + ("appfd=%d,module=%s,proto_fd=%d,ret=%d,errno=%d [return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), fdInf->rlfd, + retval, errno); } - else + else { - NSSOC_LOGINF ("appfd=%d,module=%s,proto_fd=%d,ret=%d,errno=%d [return]", - fd, nstack_get_module_name_by_idx (fdInf->rmidx), - fdInf->rlfd, retval, errno); + NSSOC_LOGINF + ("appfd=%d,module=%s,proto_fd=%d,ret=%d,errno=%d [return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), fdInf->rlfd, + retval, errno); } - UNLOCK_CONNECT (fd, local_lock); - return retval; + UNLOCK_CONNECT(fd, fdInf, local_lock); + return retval; } -int -nstack_shutdown (int fd, int how) +int nstack_shutdown(int fd, int how) { - nstack_fd_Inf *fdInf = NULL; - int retval = -1; - int tfd; + nstack_fd_Inf *fdInf = NULL; + int retval = -1; + int tfd; - if (fd < 0) + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("fd=%d invalid input [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("fd=%d invalid input [return]", fd); + return -1; } - NSTACK_INIT_CHECK_RET (shutdown, fd, how); + NSTACK_INIT_CHECK_RET(shutdown, fd, how); - NSSOC_LOGINF ("(fd=%d, how=%d) [Caller]", fd, how); + /* begin fork will close all fd(dont create by nstack) in continure, + which cause lots of log, here remove the log output */ + NSSOC_LOGINF("(fd=%d, how=%d) [Caller]", fd, how); - NSTACK_FD_LINUX_CHECK (fd, shutdown, fdInf, (fd, how)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, shutdown, fdInf, (fd, how)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON (fd, shutdown, fdInf, ENOTSOCK, - local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); - if (!fdInf->ops || -1 == fdInf->rlfd) + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON(fd, shutdown, fdInf, ENOTSOCK, + local_lock); + + if (!fdInf->ops || -1 == fdInf->rlfd) + { + NSSOC_LOGWAR("fd=%d,how=%d, shutdown fail [return]", fd, how); + nstack_set_errno(ENOTCONN); + UNLOCK_COMMON(fd, fdInf, local_lock); + return -1; + } + tfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, shutdown, (tfd, how), retval); + if ((-1 == retval) && (fdInf->rmidx != nstack_get_linux_mid())) + { + NSSOC_LOGWAR("fd=%d,ret=%d [return]", fd, retval); + } + else { - NSSOC_LOGWAR ("fd=%d,how=%d, shutdown fail [return]", fd, how); - nstack_set_errno (ENOTCONN); - UNLOCK_COMMON (fd, local_lock); - return -1; + NSSOC_LOGINF("fd=%d,ret=%d [return]", fd, retval); } - tfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, shutdown, (tfd, how), retval); - NSSOC_LOGINF ("fd=%d,ret=%d [return]", fd, retval); - UNLOCK_COMMON (fd, local_lock); - return retval; + UNLOCK_COMMON(fd, fdInf, local_lock); + return retval; } -int -release_fd (int fd, nstack_fd_local_lock_info_t * local_lock) +int release_fd(int fd, nstack_fd_local_lock_info_t * local_lock) { - nstack_fd_Inf *fdInf = NULL; - nstack_module *pMod = NULL; - int retval = 0; - int curRet = -1; - int modInx, tfd; + nstack_fd_Inf *fdInf = NULL; + nstack_module *pMod = NULL; +#ifdef KERNEL_FD_SUPPORT + int retval = -1; +#else + int retval = 0; +#endif + int curRet = -1; + int modInx, tfd; - if (!local_lock) + if (!local_lock) { - return -1; + return -1; } - LOCK_CLOSE (local_lock); + LOCK_CLOSE(local_lock); - /* if fd is used by others, just pass, delay close it */ - if (local_lock->fd_status != FD_CLOSING || local_lock->fd_ref.counter > 0) + /* if fd is used by others, just pass, delay close it */ + if (local_lock->fd_status != FD_CLOSING || local_lock->fd_ref.counter > 0) { - UNLOCK_CLOSE (local_lock); - return 0; + UNLOCK_CLOSE(local_lock); + return 0; } - local_lock->fd_status = FD_CLOSE; + local_lock->fd_status = FD_CLOSE; - fdInf = nstack_fd2inf (fd); - if (NULL == fdInf) + fdInf = nstack_fd2inf(fd); + if (NULL == fdInf) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("pstfdInf is NULL"); - UNLOCK_CLOSE (local_lock); - return -1; + nstack_set_errno(EINVAL); + NSSOC_LOGERR("pstfdInf is NULL"); + UNLOCK_CLOSE(local_lock); + return -1; } - (void) nsep_epoll_close (fd); + (void) nsep_epoll_close(fd); + + nstack_each_module(modInx, pMod) + { + tfd = nstack_get_proto_fd(fdInf, modInx); - nstack_each_module (modInx, pMod) - { - tfd = nstack_get_protoFd (fdInf, modInx); + /* add tfd rang check */ + if (nstack_get_minfd_id(modInx) > tfd + || tfd > nstack_get_maxfd_id(modInx)) + { + continue; + } - if (nstack_get_minfd_id (modInx) > tfd - || tfd > nstack_get_maxfd_id (modInx)) - { - continue; - } + NSSOC_LOGINF("fd=%d,module=%s,tfd=%d", fd, + nstack_get_module_name_by_idx(modInx), tfd); - NSSOC_LOGINF ("fd=%d,module=%s,tfd=%d", fd, - nstack_get_module_name_by_idx (modInx), tfd); +#ifdef KERNEL_FD_SUPPORT + if (0 == + strcmp(RD_KERNEL_NAME, nstack_get_module_name_by_idx(modInx))) + { + if (!(tfd >= 3 && tfd < (int) NSTACK_KERNEL_FD_MAX)) + { + NSSOC_LOGERR("tfd is out of scope]tfd=%d", tfd); + /* should release lock in this error branch */ + UNLOCK_CLOSE(local_lock); + return -1; + } - if (0 == - strcmp (nstack_fix_stack_name (), - nstack_get_module_name_by_idx (modInx))) - { - continue; - } + /* should release resource for kernel */ + continue; + } +#endif - nssct_close (fd, modInx); - NSTACK_CAL_FUN ((&pMod->mops.socket_ops), close, (tfd), curRet); + nssct_close(fd, modInx); /*do not need return value */ + NSTACK_CAL_FUN((&pMod->ops), close, (tfd), curRet); - if (-1 == curRet) - { - NSSOC_LOGERR ("failed]module=%s,tfd=%d,errno=%d", - nstack_get_module_name_by_idx (modInx), tfd, errno); - } + if (-1 == curRet) + { + NSSOC_LOGERR("failed]module=%s,tfd=%d,errno=%d", + nstack_get_module_name_by_idx(modInx), tfd, errno); + } - retval &= curRet; - } - retval &= nstack_fd_free_with_kernel (fdInf); - if (-1 == retval) +#ifdef KERNEL_FD_SUPPORT + retval &= curRet; +#else + retval |= curRet; +#endif + } +#ifdef KERNEL_FD_SUPPORT + retval &= nstack_fd_free_with_kernel(fdInf); + if (-1 == retval) { - NSSOC_LOGWAR ("fd=%d,ret=%d [return]", fd, retval); + NSSOC_LOGWAR("fd=%d,ret=%d [return]", fd, retval); } - else + else { - NSSOC_LOGINF ("fd=%d,ret=%d [return]", fd, retval); + NSSOC_LOGINF("fd=%d,ret=%d [return]", fd, retval); } +#else + nstack_fd_free(fdInf); +#endif - UNLOCK_CLOSE (local_lock); - return retval; + UNLOCK_CLOSE(local_lock); + return retval; } /*not support fork now, to support fork the module must provide gfdt & refer cnt while fork the frame use callback fun to add refer*/ -int -nstack_close (int fd) +/*vars are used in macro*/ +int nstack_close(int fd) { - nstack_fd_Inf *fdInf; - int ret = -1; + nstack_fd_Inf *fdInf; + int modInx = 0; + int ret = -1; - NSTACK_INIT_CHECK_RET (close, fd); + NSTACK_INIT_CHECK_RET(close, fd); - /*linux fd check */ - if (!(fdInf = nstack_getValidInf (fd))) +#ifdef KERNEL_FD_SUPPORT + /*linux fd check */ + if (!(fdInf = nstack_get_valid_inf(fd))) { - if (NSTACK_THREAD_LOADING ()) - { - return nsfw_base_close (fd); - } - if (0 != nstack_stack_module_load ()) + if (fd != nsep_get_manager()->checkEpollFD) { - return -1; - } - if (nstack_fix_fd_check () - && nstack_fix_fd_check ()(fd, STACK_FD_FUNCALL_CHECK)) - { - /*free epoll resoure */ - nsep_epoll_close (fd); - nssct_close (fd, nstack_get_fix_mid ()); + /*free epoll resouce */ + nsep_epoll_close(fd); /*do not need return value */ + nssct_close(fd, nstack_get_linux_mid()); /*do not need return value */ - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (fd), ret); - return ret; + return nsfw_base_close(fd); } - nstack_set_errno (ENOSYS); - return -1; + nstack_set_errno(ENOSYS); + return -1; } +#else + NSTACK_FD_LINUX_CHECK_RETURN(fd, close, fdInf, (fd)); +#endif - NSSOC_LOGINF ("Caller]fd=%d", fd); + NSSOC_LOGINF("Caller]fd=%d", fd); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_CLOSE (local_lock); - if (local_lock->fd_status != FD_OPEN) + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_CLOSE(local_lock); + if (local_lock->fd_status != FD_OPEN) { - NSSOC_LOGERR ("return]fd_status=%d,fd=%d", local_lock->fd_status, fd); - nstack_set_errno (EBADF); - UNLOCK_CLOSE (local_lock); - return -1; + NSSOC_LOGERR("return]fd_status=%d,fd=%d", local_lock->fd_status, fd); + nstack_set_errno(EBADF); + UNLOCK_CLOSE(local_lock); + return -1; } - set_fd_status_lock_fork (fd, FD_CLOSING); + set_fd_status_lock_fork(fd, FD_CLOSING); - UNLOCK_CLOSE (local_lock); - ret = - (atomic_dec (&local_lock->fd_ref) > 0 ? 0 : release_fd (fd, local_lock)); + /* add fdInf->rlfd and fdInf->ops's validity check,avoid + print error log in normal scenario */ + if (NSTACK_IS_FD_ATTR(fdInf, fdInf->rd_item.type_data.attr) + && (-1 != fdInf->rlfd) && fdInf->ops) + { + nstack_each_mod_inx(modInx) + { + if (nstack_fd_deal[modInx].set_close_stat) + { + nstack_fd_deal[modInx].set_close_stat(fdInf->rlfd, + FD_CLOSING); + } + } + } - if (-1 == ret) + UNLOCK_CLOSE(local_lock); + ret = + (atomic_dec(&local_lock->fd_ref) > + 0 ? 0 : release_fd(fd, local_lock)); + + if (-1 == ret) { - NSSOC_LOGWAR ("return]fd=%d,retVal=%d", fd, ret); + NSSOC_LOGWAR("return]fd=%d,retVal=%d", fd, ret); } - else + else { - NSSOC_LOGINF ("return]fd=%d,retVal=%d", fd, ret); + NSSOC_LOGINF("return]fd=%d,retVal=%d", fd, ret); } - return ret; + return ret; } -ssize_t -nstack_send (int fd, const void *buf, size_t len, int flags) +ssize_t nstack_send(int fd, const void *buf, size_t len, int flags) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; - NSTACK_INIT_CHECK_RET (send, fd, buf, len, flags); + NSTACK_INIT_CHECK_RET(send, fd, buf, len, flags); - NS_LOG_CTRL (LOG_CTRL_SEND, NSOCKET, "NSSOC", NSLOG_DBG, - "(sockfd=%d, buf=%p, len=%zu, flags=%d) [Caller]", fd, buf, - len, flags); + NS_LOG_CTRL(LOG_CTRL_SEND, NSOCKET, "SOC", NSLOG_DBG, + "sockfd=%d,buf=%p,len=%zu,flags=%d[Caller]", fd, buf, len, + flags); - NSTACK_FD_LINUX_CHECK (fd, send, fdInf, (fd, buf, len, flags)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, send, fdInf, (fd, buf, len, flags)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_SEND (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND (fd, send, fdInf, ENOTSOCK, - local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_SEND(fd, fdInf, local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, send, fdInf, ENOTSOCK, + local_lock); + + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGINF ("fd Fail: Not select any module yet!]fd=%d [return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_SEND (fd, local_lock); - return -1; + NSSOC_LOGINF("fd Fail: Not select any module yet]fd=%d[return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_SEND(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, send, (fdInf->rlfd, buf, len, flags), size); - - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, send, (fdInf->rlfd, buf, len, flags), size); - UNLOCK_SEND (fd, local_lock); - return size; + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_recv (int fd, void *buf, size_t len, int flags) +ssize_t nstack_recv(int fd, void *buf, size_t len, int flags) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; - NSTACK_INIT_CHECK_RET (recv, fd, buf, len, flags); + NSTACK_INIT_CHECK_RET(recv, fd, buf, len, flags); - NS_LOG_CTRL (LOG_CTRL_RECV, NSOCKET, "NSSOC", NSLOG_DBG, - "(sockfd=%d, buf=%p, len=%zu, flags=%d) [Caller]", fd, buf, - len, flags); + NS_LOG_CTRL(LOG_CTRL_RECV, NSOCKET, "SOC", NSLOG_DBG, + "sockfd=%d,buf=%p,len=%zu,flags=%d[Caller]", fd, buf, len, + flags); - NSTACK_FD_LINUX_CHECK (fd, recv, fdInf, (fd, buf, len, flags)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, recv, fdInf, (fd, buf, len, flags)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_RECV (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV (fd, recv, fdInf, ENOTSOCK, - local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_RECV(fd, fdInf, local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fd, recv, fdInf, ENOTSOCK, + local_lock); + + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGINF ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_RECV (fd, local_lock); - return -1; + NSSOC_LOGINF("Not select any module yet]fd=%d[Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_RECV(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, recv, (fdInf->rlfd, buf, len, flags), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, recv, (fdInf->rlfd, buf, len, flags), size); - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); - UNLOCK_RECV (fd, local_lock); - return size; + UNLOCK_RECV(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_write (int fd, const void *buf, size_t count) +ssize_t nstack_write(int fd, const void *buf, size_t count) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; - NSTACK_INIT_CHECK_RET (write, fd, buf, count); + NSTACK_INIT_CHECK_RET(write, fd, buf, count); - NSTACK_FD_LINUX_CHECK (fd, write, fdInf, (fd, buf, count)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, write, fdInf, (fd, buf, count)); + NS_LOG_CTRL(LOG_CTRL_WRITE, NSOCKET, "SOC", NSLOG_DBG, + "fd=%d,buf=%p,count=%zu[Caller]", fd, buf, count); - NS_LOG_CTRL (LOG_CTRL_WRITE, NSOCKET, "NSSOC", NSLOG_DBG, - "(fd=%d, buf=%p, count=%zu) [Caller]", fd, buf, count); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_SEND(fd, fdInf, local_lock); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_SEND (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND (fd, write, fdInf, EINVAL, - local_lock); + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, write, fdInf, EINVAL, + local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGINF ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_SEND (fd, local_lock); - return -1; + NSSOC_LOGINF("Not select any module yet]fd=%d[Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_SEND(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, write, (fdInf->rlfd, buf, count), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, write, (fdInf->rlfd, buf, count), size); - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); - UNLOCK_SEND (fd, local_lock); - return size; + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_read (int fd, void *buf, size_t count) +ssize_t nstack_read(int fd, void *buf, size_t count) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; + + NSTACK_INIT_CHECK_RET(read, fd, buf, count); - NSTACK_INIT_CHECK_RET (read, fd, buf, count); + NS_LOG_CTRL(LOG_CTRL_READ, NSOCKET, "SOC", NSLOG_DBG, + "fd=%d,buf=%p,count=%zu[Caller]", fd, buf, count); - NS_LOG_CTRL (LOG_CTRL_READ, NSOCKET, "NSSOC", NSLOG_DBG, - "(fd=%d, buf=%p, count=%zu) [Caller]", fd, buf, count); + NSTACK_FD_LINUX_CHECK_RETURN(fd, read, fdInf, (fd, buf, count)); - NSTACK_FD_LINUX_CHECK (fd, read, fdInf, (fd, buf, count)); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_RECV(fd, fdInf, local_lock); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_RECV (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV (fd, read, fdInf, EINVAL, local_lock); + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fd, read, fdInf, EINVAL, + local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGINF ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_RECV (fd, local_lock); - return -1; + NSSOC_LOGINF("Not select any module yet]fd=%d[Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_RECV(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, read, (fdInf->rlfd, buf, count), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, read, (fdInf->rlfd, buf, count), size); - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); - UNLOCK_RECV (fd, local_lock); - return size; + UNLOCK_RECV(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_writev (int fd, const struct iovec * iov, int iovcnt) +ssize_t nstack_writev(int fd, const struct iovec * iov, int iovcnt) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; - NSTACK_INIT_CHECK_RET (writev, fd, iov, iovcnt); + NSTACK_INIT_CHECK_RET(writev, fd, iov, iovcnt); - NS_LOG_CTRL (LOG_CTRL_WRITEV, NSOCKET, "NSSOC", NSLOG_DBG, - "(fd=%d, iov=%p, count=%d) [Caller]", fd, iov, iovcnt); + NS_LOG_CTRL(LOG_CTRL_WRITEV, NSOCKET, "SOC", NSLOG_DBG, + "fd=%d,iov=%p,count=%d[Caller]", fd, iov, iovcnt); - NSTACK_FD_LINUX_CHECK (fd, writev, fdInf, (fd, iov, iovcnt)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, writev, fdInf, (fd, iov, iovcnt)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_SEND (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND (fd, writev, fdInf, EINVAL, - local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_SEND(fd, fdInf, local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, writev, fdInf, EINVAL, + local_lock); + + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGERR ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_SEND (fd, local_lock); - return -1; + NSSOC_LOGERR("Not select any module yet]fd=%d[Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_SEND(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, writev, (fdInf->rlfd, iov, iovcnt), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, writev, (fdInf->rlfd, iov, iovcnt), size); - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); - UNLOCK_SEND (fd, local_lock); - return size; + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_readv (int fd, const struct iovec * iov, int iovcnt) +ssize_t nstack_readv(int fd, const struct iovec * iov, int iovcnt) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; + + NSTACK_INIT_CHECK_RET(readv, fd, iov, iovcnt); - NSTACK_INIT_CHECK_RET (readv, fd, iov, iovcnt); + NS_LOG_CTRL(LOG_CTRL_READV, NSOCKET, "SOC", NSLOG_DBG, + "fd=%d,iov=%p,count=%d[Caller]", fd, iov, iovcnt); - NS_LOG_CTRL (LOG_CTRL_READV, NSOCKET, "NSSOC", NSLOG_DBG, - "(fd=%d, iov=%p, count=%d) [Caller]", fd, iov, iovcnt); + NSTACK_FD_LINUX_CHECK_RETURN(fd, readv, fdInf, (fd, iov, iovcnt)); - NSTACK_FD_LINUX_CHECK (fd, readv, fdInf, (fd, iov, iovcnt)); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_RECV(fd, fdInf, local_lock); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_RECV (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV (fd, readv, fdInf, EINVAL, - local_lock); + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fd, readv, fdInf, EINVAL, + local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGERR ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_RECV (fd, local_lock); - return -1; + NSSOC_LOGERR("Not select any module yet]fd=%d [Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_RECV(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, readv, (fdInf->rlfd, iov, iovcnt), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, readv, (fdInf->rlfd, iov, iovcnt), size); - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); - UNLOCK_RECV (fd, local_lock); - return size; + UNLOCK_RECV(fd, fdInf, local_lock); + return size; } /*we assumed that the connect allready called, if not call, we must try many sok*/ -ssize_t -nstack_sendto (int fd, const void *buf, size_t len, int flags, - const struct sockaddr * dest_addr, socklen_t addrlen) +ssize_t nstack_sendto(int fd, const void *buf, size_t len, int flags, + const struct sockaddr * dest_addr, socklen_t addrlen) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; - struct sockaddr_in *iaddr = NULL; - int selectmod = -1; - int retval = 0; - nstack_rd_key rdkey = { 0 }; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; + int retval = 0; - NSTACK_INIT_CHECK_RET (sendto, fd, buf, len, flags, dest_addr, addrlen); + ns_udp_route_Inf udp_route_info; - NSSOC_LOGDBG - ("(sockfd=%d, buf=%p, len=%zu, flags=%d, dest_addr=%p, addrlen=%u) [Caller]", - fd, buf, len, flags, dest_addr, addrlen); + NSTACK_INIT_CHECK_RET(sendto, fd, buf, len, flags, dest_addr, addrlen); - NSTACK_FD_LINUX_CHECK (fd, sendto, fdInf, - (fd, buf, len, flags, dest_addr, addrlen)); + NSSOC_LOGDBG + ("sockfd=%d, buf=%p,len=%zu,flags=%d,dest_addr=%p,addrlen=%u[Caller]", + fd, buf, len, flags, dest_addr, addrlen); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_SEND (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND (fd, sendto, fdInf, ENOTSOCK, - local_lock); + NSTACK_FD_LINUX_CHECK_RETURN(fd, sendto, fdInf, + (fd, buf, len, flags, dest_addr, addrlen)); - if (fdInf->ops) + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_SEND(fd, fdInf, local_lock); + + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, sendto, fdInf, ENOTSOCK, + local_lock); + + if (fdInf->ops) { - NSTACK_CAL_FUN (fdInf->ops, sendto, - (fdInf->rlfd, buf, len, flags, dest_addr, addrlen), - size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, sendto, + (fdInf->rlfd, buf, len, flags, dest_addr, addrlen), + size); - NSSOC_LOGDBG - ("fdInf->ops:fd=%d buf=%p,len=%zu,size=%d,addr=%p [Return]", fd, buf, - len, size, dest_addr); - UNLOCK_SEND (fd, local_lock); - return size; + NSSOC_LOGDBG + ("fdInf->ops]fd=%d buf=%p,len=%zu,size=%zd,addr=%p[Return]", fd, + buf, len, size, dest_addr); + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } - /*invalid ip, just return */ - /*validity check for addrlen: for visite iaddr->sin_addr.s_addr is 8 byte */ - if ((NULL == dest_addr) || (addrlen < 8)) + /*invalid ip, just return */ + /* add validity check for addrlen: for visite iaddr->sin_addr.s_addr is 8 byte */ + if ((NULL == dest_addr) || (addrlen < 8)) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("invalid input]fd=%d,buf=%p,len=%zu,addr=%p [Return]", fd, - buf, len, dest_addr); - UNLOCK_SEND (fd, local_lock); - return -1; + nstack_set_errno(EINVAL); + NSSOC_LOGERR("invalid input]fd=%d,buf=%p,len=%zu,addr=%p[Return]", + fd, buf, len, dest_addr); + UNLOCK_SEND(fd, fdInf, local_lock); + return -1; } - iaddr = (struct sockaddr_in *) dest_addr; - rdkey.type = RD_DATA_TYPE_IP; - rdkey.ip_addr = iaddr->sin_addr.s_addr; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod == -1)) - { - rdkey.type = RD_DATA_TYPE_PROTO; - rdkey.proto_type = fdInf->type; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod < 0) - || (selectmod >= nstack_get_modNum ())) - { - NSSOC_LOGINF ("fd=%d addr=%s Select module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - selectmod = -1; - } - else - { - NSSOC_LOGINF ("sendto socket of]select modName=%s", - nstack_get_module_name_by_idx (selectmod)); - } - } - if ((ns_success == retval) && (selectmod >= 0)) + retval = nstack_socket_get_stackid(fdInf, dest_addr, addrlen); + + if ((ns_success == retval) && (fdInf->rd_item.stack_id != -1)) { - NSSOC_LOGINF ("fd=%d,addr=%s,select_module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - fdInf->rmidx = selectmod; - nstack_set_routed_fd (fdInf, nstack_get_protoFd (fdInf, selectmod)); - nstack_set_router_protocol (fdInf, selectmod); - fdInf->ops = nstack_module_ops (selectmod); + NSSOC_LOGINF("fd=%d,addr=%s,select_module=%s, rd_opt=%d", fd, + inet_ntoa_x(dest_addr), + nstack_get_module_name_by_idx(fdInf->rd_item.stack_id), + fdInf->rd_opt); + fdInf->rmidx = fdInf->rd_item.stack_id; + nstack_set_routed_fd(fdInf, + nstack_get_proto_fd(fdInf, + fdInf->rd_item.stack_id)); + nstack_set_router_protocol(fdInf, fdInf->rd_item.stack_id); + fdInf->ops = nstack_module_ops(fdInf->rd_item.stack_id); + + udp_route_info.iaddr = *(struct sockaddr_in *) dest_addr; + udp_route_info.selectmod = fdInf->rd_item.stack_id; + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_ROUTE_INFO, &udp_route_info); + } - else + else { - NSSOC_LOGERR ("fd=%d Callback select module=%d,ret=0x%x", fd, selectmod, - retval); - nstack_set_errno (ENETUNREACH); - UNLOCK_SEND (fd, local_lock); - return -1; + NSSOC_LOGERR("fd=%d Callback select module=%d, rd_opt=%d, ret=0x%x", + fd, fdInf->rd_item.stack_id, fdInf->rd_opt, retval); + nstack_set_errno(ENETUNREACH); + UNLOCK_SEND(fd, fdInf, local_lock); + return -1; } - NSSOC_LOGDBG ("fd=%d,addr=%s,select_module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); + NSSOC_LOGDBG("fd=%d,addr=%s,select_module=%s,rd_opt=%d", fd, + inet_ntoa_x(dest_addr), + nstack_get_module_name_by_idx(fdInf->rd_item.stack_id), + fdInf->rd_opt); - NSTACK_CAL_FUN (fdInf->ops, sendto, - (fdInf->rlfd, buf, len, flags, dest_addr, addrlen), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, sendto, + (fdInf->rlfd, buf, len, flags, dest_addr, addrlen), size); - NSSOC_LOGDBG ("fd=%d,module=%s,ret=%d [Return]", fd, - nstack_get_module_name_by_idx (fdInf->rmidx), size); + NSSOC_LOGDBG("fd=%d,module=%s,ret=%d[Return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), size); - UNLOCK_SEND (fd, local_lock); - return size; + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_sendmsg (int fd, const struct msghdr * msg, int flags) +ssize_t nstack_sendmsg(int fd, const struct msghdr * msg, int flags) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; - struct sockaddr_in *iaddr = NULL; - int selectmod = -1; - int retval = 0; - nstack_rd_key rdkey = { 0 }; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; + struct sockaddr *addr = NULL; + int retval = 0; - NSTACK_INIT_CHECK_RET (sendmsg, fd, msg, flags); + NSTACK_INIT_CHECK_RET(sendmsg, fd, msg, flags); - NS_LOG_CTRL (LOG_CTRL_SENDMSG, NSOCKET, "NSSOC", NSLOG_DBG, - "(sockfd=%d, msg=%p, flags=%d) [Caller]", fd, msg, flags); + NS_LOG_CTRL(LOG_CTRL_SENDMSG, NSOCKET, "SOC", NSLOG_DBG, + "sockfd=%d,msg=%p,flags=%d[Caller]", fd, msg, flags); - if (NULL == msg) + if (NULL == msg) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("invalid input]fd=%d,msg=%p [Return]", fd, msg); - return -1; + nstack_set_errno(EINVAL); + NSSOC_LOGERR("invalid input]fd=%d,msg=%p[Return]", fd, msg); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, sendmsg, fdInf, (fd, msg, flags)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, sendmsg, fdInf, (fd, msg, flags)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_SEND (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND (fd, sendmsg, fdInf, ENOTSOCK, - local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_SEND(fd, fdInf, local_lock); - /*if some module select, just connect */ - if (fdInf->ops) - { - NSTACK_CAL_FUN (fdInf->ops, sendmsg, (fdInf->rlfd, msg, flags), size); - NSSOC_LOGDBG ("]fd=%d,size=%d msg=%p [Return]", fd, size, msg); - UNLOCK_SEND (fd, local_lock); - return size; - } + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, sendmsg, fdInf, ENOTSOCK, + local_lock); - iaddr = (struct sockaddr_in *) msg->msg_name; - /* validity check for msg->msg_namelen,for visite iaddr->sin_addr.s_addr is 8 byte */ - if ((NULL == iaddr) || (msg->msg_namelen < 8)) + /*if some module select, just connect */ + if (fdInf->ops) { - NSSOC_LOGINF ("fd addr is null and select linux module]fd=%d", fd); - fdInf->ops = nstack_module_ops (nstack_get_fix_mid ()); - nstack_set_routed_fd (fdInf, - nstack_get_protoFd (fdInf, - nstack_get_fix_mid ())); - nstack_set_router_protocol (fdInf, nstack_get_fix_mid ()); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, sendmsg, (fdInf->rlfd, msg, flags), size); + + NSSOC_LOGDBG("]fd=%d,size=%zd msg=%p[Return]", fd, size, msg); + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } - else + + /* add validity check for msg->msg_namelen,for visite iaddr->sin_addr.s_addr is 8 byte */ + addr = (struct sockaddr *) msg->msg_name; + if ((fdInf->rd_opt != -1) || ((NULL != addr) && (msg->msg_namelen >= 8))) { - rdkey.type = RD_DATA_TYPE_IP; - rdkey.ip_addr = iaddr->sin_addr.s_addr; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod == -1)) + retval = nstack_socket_get_stackid(fdInf, addr, msg->msg_namelen); + if (ns_success == retval && fdInf->rd_item.stack_id != -1) { - rdkey.type = RD_DATA_TYPE_PROTO; - rdkey.proto_type = fdInf->type; - retval = nstack_rd_get_stackid (&rdkey, &selectmod); - if ((0 != retval) || (selectmod < 0) - || (selectmod >= nstack_get_modNum ())) + if (NULL != addr) { - NSSOC_LOGINF ("fd=%d addr=%s Select module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - selectmod = -1; + NSSOC_LOGINF("fd=%d,addr=%s,select_module=%s, rd_opt=%d", fd, + inet_ntoa_x(addr), + nstack_get_module_name_by_idx(fdInf-> + rd_item.stack_id), + fdInf->rd_opt); } - else + else { - NSSOC_LOGINF ("Connect socket of]select modName=%s", - nstack_get_module_name_by_idx (selectmod)); + NSSOC_LOGINF("fd=%d,select_module=%s, rd_opt=%d", fd, + nstack_get_module_name_by_idx(fdInf-> + rd_item.stack_id), + fdInf->rd_opt); } + + fdInf->rmidx = fdInf->rd_item.stack_id; + nstack_set_routed_fd(fdInf, + nstack_get_proto_fd(fdInf, + fdInf-> + rd_item.stack_id)); + nstack_set_router_protocol(fdInf, fdInf->rd_item.stack_id); + fdInf->ops = nstack_module_ops(fdInf->rd_item.stack_id); } - if (ns_success == retval) - { - NSSOC_LOGINF ("fd=%d,addr=%s,select_module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); - fdInf->rmidx = selectmod; - nstack_set_routed_fd (fdInf, nstack_get_protoFd (fdInf, selectmod)); - nstack_set_router_protocol (fdInf, selectmod); - fdInf->ops = nstack_module_ops (selectmod); - } - else + else { - NSSOC_LOGERR ("fd=%d Callback select_module=%d,ret=0x%x", fd, - selectmod, retval); - nstack_set_errno (ENETUNREACH); - UNLOCK_SEND (fd, local_lock); - return -1; + NSSOC_LOGERR + ("fd=%d Callback select_module=%d, rd_opt=%d, ret=0x%x", fd, + fdInf->rd_item.stack_id, fdInf->rd_opt, retval); + nstack_set_errno(ENETUNREACH); + UNLOCK_SEND(fd, fdInf, local_lock); + return -1; } - NSSOC_LOGDBG ("fd=%d,addr=%s,select_module=%s", - fd, inet_ntoa (iaddr->sin_addr), - nstack_get_module_name_by_idx (selectmod)); + NSSOC_LOGDBG("fd=%d,select_module=%s", fd, + nstack_get_module_name_by_idx(fdInf->rd_item.stack_id)); } + else + { + NSSOC_LOGINF("fd addr is null and select linux module]fd=%d", fd); + fdInf->ops = nstack_module_ops(nstack_get_linux_mid()); + nstack_set_routed_fd(fdInf, + nstack_get_proto_fd(fdInf, + nstack_get_linux_mid())); + nstack_set_router_protocol(fdInf, nstack_get_linux_mid()); + } + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_SEND_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, sendmsg, (fdInf->rlfd, msg, flags), size); - NSTACK_CAL_FUN (fdInf->ops, sendmsg, (fdInf->rlfd, msg, flags), size); - - NSSOC_LOGDBG ("fd=%d,module=%s,ret=%d [Return]", fd, - nstack_get_module_name_by_idx (fdInf->rmidx), size); + NSSOC_LOGDBG("fd=%d,module=%s,ret=%d[Return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), size); - UNLOCK_SEND (fd, local_lock); - return size; + UNLOCK_SEND(fd, fdInf, local_lock); + return size; } /*we assumed that the connect allready called, if not call, we must try many sok*/ -ssize_t -nstack_recvfrom (int fd, void *buf, size_t len, int flags, - struct sockaddr * src_addr, socklen_t * addrlen) +ssize_t nstack_recvfrom(int fd, void *buf, size_t len, int flags, + struct sockaddr * src_addr, socklen_t * addrlen) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; - NSTACK_INIT_CHECK_RET (recvfrom, fd, buf, len, flags, src_addr, addrlen); + NSTACK_INIT_CHECK_RET(recvfrom, fd, buf, len, flags, src_addr, addrlen); - NSSOC_LOGDBG - ("(sockfd=%d, buf=%p, len=%zu, flags=%d, src_addr=%p, addrlen=%p) [Caller]", - fd, buf, len, flags, src_addr, addrlen); + NSSOC_LOGDBG + ("sockfd=%d,buf=%p,len=%zu,flags=%d,src_addr=%p,addrlen=%p[Caller]", + fd, buf, len, flags, src_addr, addrlen); - if (NULL == buf) + if (NULL == buf) { - nstack_set_errno (EFAULT); - NSSOC_LOGERR ("invalid input]fd=%d,buf=%p [Return]", fd, buf); - return -1; + nstack_set_errno(EFAULT); + NSSOC_LOGERR("invalid input]fd=%d,buf=%p[Return]", fd, buf); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, recvfrom, fdInf, - (fd, buf, len, flags, src_addr, addrlen)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, recvfrom, fdInf, + (fd, buf, len, flags, src_addr, addrlen)); + + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_RECV(fd, fdInf, local_lock); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_RECV (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV (fd, recvfrom, fdInf, ENOTSOCK, - local_lock); + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fd, recvfrom, fdInf, ENOTSOCK, + local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + if ((!fdInf->ops) || (-1 == fdInf->rlfd)) { - NSSOC_LOGINF ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_RECV (fd, local_lock); - return -1; + NSSOC_LOGINF("Not select any module yet]fd=%d[Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_RECV(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, recvfrom, - (fdInf->rlfd, buf, len, flags, src_addr, addrlen), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, recvfrom, + (fdInf->rlfd, buf, len, flags, src_addr, addrlen), size); - NSSOC_LOGDBG ("fd=%d,retVal=%d [Return]", fd, size); + NSSOC_LOGDBG("fd=%d,retVal=%zd[Return]", fd, size); - UNLOCK_RECV (fd, local_lock); - return size; + UNLOCK_RECV(fd, fdInf, local_lock); + return size; } -ssize_t -nstack_recvmsg (int fd, struct msghdr * msg, int flags) +ssize_t nstack_recvmsg(int fd, struct msghdr * msg, int flags) { - nstack_fd_Inf *fdInf = NULL; - int size = -1; + nstack_fd_Inf *fdInf = NULL; + ssize_t size = -1; - NSTACK_INIT_CHECK_RET (recvmsg, fd, msg, flags); + NSTACK_INIT_CHECK_RET(recvmsg, fd, msg, flags); + NS_LOG_CTRL(LOG_CTRL_RECVMSG, NSOCKET, "SOC", NSLOG_DBG, + "sockfd=%d,msg=%p,flags=%d[Caller]", fd, msg, flags); - NS_LOG_CTRL (LOG_CTRL_RECVMSG, NSOCKET, "NSSOC", NSLOG_DBG, - "(sockfd=%d, msg=%p, flags=%d) [Caller]", fd, msg, flags); + NSTACK_FD_LINUX_CHECK_RETURN(fd, recvmsg, fdInf, (fd, msg, flags)); - NSTACK_FD_LINUX_CHECK (fd, recvmsg, fdInf, (fd, msg, flags)); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_RECV(fd, fdInf, local_lock); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_RECV (fd, fdInf, local_lock); - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV (fd, recvmsg, fdInf, ENOTSOCK, - local_lock); + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fd, recvmsg, fdInf, ENOTSOCK, + local_lock); - if ((-1 == fdInf->rlfd) || (NULL == fdInf->ops)) + if ((-1 == fdInf->rlfd) || (NULL == fdInf->ops)) { - NSSOC_LOGERR ("Not select any module yet!]fd=%d [Return]", fd); - nstack_set_errno (ENOTCONN); - UNLOCK_RECV (fd, local_lock); - return -1; + NSSOC_LOGERR("Not select any module yet]fd=%d[Return]", fd); + nstack_set_errno(ENOTCONN); + UNLOCK_RECV(fd, fdInf, local_lock); + return -1; } - NSTACK_CAL_FUN (fdInf->ops, recvmsg, (fdInf->rlfd, msg, flags), size); + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_INTERVAL, NULL); + NSTACK_CAL_FUN(fdInf->ops, recvmsg, (fdInf->rlfd, msg, flags), size); + + NSSOC_LOGDBG("fd=%d,ret=%zd[Return]", fd, size); + + UNLOCK_RECV(fd, fdInf, local_lock); + return size; +} + +/***************************************************************** +Parameters : fd + addr + len +Return : +Description : use hostname to get ip or use ip to get hostname +*****************************************************************/ +int nstack_getaddrinfo(const char *name, const char *service, + const struct addrinfo *hints, struct addrinfo **res) +{ + int ret = 0; - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, size); + g_addrinfo_flag = 1; + ret = nsfw_base_getaddrinfo(name, service, hints, res); + g_addrinfo_flag = 0; - UNLOCK_RECV (fd, local_lock); - return size; + return ret; } /***************************************************************** @@ -1650,68 +2041,68 @@ Parameters : fd Return : Description : all module fd bind to same addr, so just use first rlfd to get bind addr. *****************************************************************/ -int -nstack_getsockname (int fd, struct sockaddr *addr, socklen_t * addrlen) +int nstack_getsockname(int fd, struct sockaddr *addr, socklen_t * addrlen) { - nstack_fd_Inf *fdInf = NULL; - int tfd = -1; - int ret = -1; + nstack_fd_Inf *fdInf = NULL; + int tfd = -1; + int ret = -1; - NSTACK_INIT_CHECK_RET (getsockname, fd, addr, addrlen); + NSTACK_INIT_CHECK_RET(getsockname, fd, addr, addrlen); - NS_LOG_CTRL (LOG_CTRL_GETSOCKNAME, NSOCKET, "NSSOC", NSLOG_INF, - "(fd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, addrlen); + NS_LOG_CTRL(LOG_CTRL_GETSOCKNAME, NSOCKET, "SOC", NSLOG_INF, + "fd=%d,addr=%p,addrlen=%p[Caller]", fd, addr, addrlen); - if (fd < 0) + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d. [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d[return]", fd); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, getsockname, fdInf, (fd, addr, addrlen)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, getsockname, fdInf, (fd, addr, addrlen)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); - if ((NULL != fdInf->ops) && (fdInf->rlfd != -1)) + if ((NULL != fdInf->ops) && (fdInf->rlfd != -1)) { - tfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, getsockname, (tfd, addr, addrlen), ret); - NSSOC_LOGINF ("fd=%d,module=%s,tfd=%d [return]", fd, - nstack_get_module_name_by_idx (fdInf->rmidx), tfd); - if (-1 == ret) + tfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, getsockname, (tfd, addr, addrlen), ret); + NSSOC_LOGINF("fd=%d,module=%s,tfd=%d[return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), tfd); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) { - NSSOC_LOGERR ("rmidx=%d,fd=%d return fail [return]", fdInf->rmidx, - tfd); + NSSOC_LOGERR("rmidx=%d,fd=%d return fail[return]", fdInf->rmidx, + tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } - if (NULL != g_nstack_modules.defMod) + if (NULL != g_nstack_modules.defMod) { - tfd = nstack_get_protoFd (fdInf, nstack_defMod_inx ()); - if (tfd >= 0) + tfd = nstack_get_proto_fd(fdInf, nstack_defmod_inx()); + if (tfd >= 0) { - nstack_socket_ops *ops = nstack_def_ops (); - NSTACK_CAL_FUN (ops, getsockname, (tfd, addr, addrlen), ret); - NSSOC_LOGINF ("fd=%d,module=%s,tfd=%d [return]", fd, - nstack_defmod_name (), tfd); - if (-1 == ret) + nstack_socket_ops *ops = nstack_def_ops(); + NSTACK_CAL_FUN(ops, getsockname, (tfd, addr, addrlen), ret); + NSSOC_LOGINF("fd=%d,module=%s,tfd=%d[return]", fd, + nstack_defmod_name(), tfd); + if ((-1 == ret) + && (nstack_defmod_inx() != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d [return]", - nstack_defMod_inx (), tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d[return]", + nstack_defmod_inx(), tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } } - nstack_set_errno (ENOTSOCK); - NSSOC_LOGINF ("fd=%d,ret=%d [Return]", fd, ret); - UNLOCK_COMMON (fd, local_lock); - return ret; + nstack_set_errno(ENOTSOCK); + NSSOC_LOGINF("fd=%d,ret=%d [Return]", fd, ret); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } @@ -1720,1148 +2111,1065 @@ Parameters : fd addr len Return : -Description : getpeername only used by the fd who already Establish connection, so use first rlfd. +Description : getpeername only used by the fd who already Estblsh connection, so use first rlfd. *****************************************************************/ -int -nstack_getpeername (int fd, struct sockaddr *addr, socklen_t * addrlen) +int nstack_getpeername(int fd, struct sockaddr *addr, socklen_t * addrlen) { - nstack_fd_Inf *fdInf; - int tfd; - int ret = -1; + nstack_fd_Inf *fdInf; + int tfd; + int ret = -1; - NSTACK_INIT_CHECK_RET (getpeername, fd, addr, addrlen); + NSTACK_INIT_CHECK_RET(getpeername, fd, addr, addrlen); - NS_LOG_CTRL (LOG_CTRL_GETPEERNAME, NSOCKET, "NSSOC", NSLOG_INF, - "(fd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, addrlen); + NS_LOG_CTRL(LOG_CTRL_GETPEERNAME, NSOCKET, "SOC", NSLOG_INF, + "fd=%d,addr=%p,addrlen=%p[Caller]", fd, addr, addrlen); - if (fd < 0) + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input, fd=%d. [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input,fd=%d[return]", fd); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, getpeername, fdInf, (fd, addr, addrlen)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, getpeername, fdInf, (fd, addr, addrlen)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); - /*?????????,????????????? */ - if (fdInf->ops) + if (fdInf->ops) { - tfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, getpeername, (tfd, addr, addrlen), ret); - NSSOC_LOGINF ("fd=%d,module=%s,rlfd=%d,ret=%d [return]", - fd, nstack_get_module_name_by_idx (fdInf->rmidx), - fdInf->rlfd, ret); - if (-1 == ret) + tfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, getpeername, (tfd, addr, addrlen), ret); + NSSOC_LOGINF("fd=%d,module=%s,rlfd=%d,ret=%d[return]", + fd, nstack_get_module_name_by_idx(fdInf->rmidx), + fdInf->rlfd, ret); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d [return]", fdInf->rmidx, - tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d[return]", fdInf->rmidx, + tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } - if (NULL != g_nstack_modules.defMod) + if (NULL != g_nstack_modules.defMod) { - tfd = nstack_get_protoFd (fdInf, nstack_defMod_inx ()); - if (tfd >= 0) + tfd = nstack_get_proto_fd(fdInf, nstack_defmod_inx()); + if (tfd >= 0) { - nstack_socket_ops *ops = nstack_def_ops (); - NSTACK_CAL_FUN (ops, getpeername, (tfd, addr, addrlen), ret); - NSSOC_LOGINF ("fd=%d,module=%s,tfd=%d [return]", fd, - nstack_defmod_name (), tfd); - if (-1 == ret) + nstack_socket_ops *ops = nstack_def_ops(); + NSTACK_CAL_FUN(ops, getpeername, (tfd, addr, addrlen), ret); + NSSOC_LOGINF("fd=%d,module=%s,tfd=%d[return]", fd, + nstack_defmod_name(), tfd); + if ((-1 == ret) + && (nstack_defmod_inx() != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail] module=%d,fd=%d [return]", - nstack_defMod_inx (), tfd); + NSSOC_LOGERR("return fail] mudle=%d,fd=%d[return]", + nstack_defmod_inx(), tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } } - nstack_set_errno (ENOTSOCK); - NSSOC_LOGINF ("fd=%d,ret=%d [Return]", fd, ret); - UNLOCK_COMMON (fd, local_lock); - return ret; + nstack_set_errno(ENOTSOCK); + NSSOC_LOGINF("fd=%d,ret=%d[Return]", fd, ret); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } -int -nstack_option_set (nstack_fd_Inf * fdInf, int optname, const void *optval, - socklen_t optlen) +int nstack_option_set(nstack_fd_Inf * fdInf, int optname, const void *optval, + socklen_t optlen) { + ns_int32 rd_opt; #define SLEEP_MAX 10000000 - if ((!optval) || (optlen < sizeof (u32_t))) + if ((!optval) || (optlen < sizeof(u32_t))) { - NSSOC_LOGINF ("rong parmeter optname]=%d", optname); - nstack_set_errno (EINVAL); - return -1; + NSSOC_LOGINF("rong parmeter optname]=%d", optname); + nstack_set_errno(EINVAL); + return -1; } - switch (optname) + switch (optname) { - case NSTACK_SEM_SLEEP: - if ((*(u32_t *) optval) > SLEEP_MAX) - { - NSSOC_LOGWAR ("time overflow]epfd=%d", fdInf->fd); - nstack_set_errno (EINVAL); - return -1; - } - - nsep_set_infoSleepTime (fdInf->fd, *(u32_t *) optval); - NSSOC_LOGINF ("set sem wait option] g_sem_sleep_time=%ld", - *(u32_t *) optval); - break; + case NSTACK_SEM_SLEEP: + if ((*(u32_t *) optval) > SLEEP_MAX) + { + NSSOC_LOGWAR("time overflow]epfd=%d", fdInf->fd); + nstack_set_errno(EINVAL); + return -1; + } - default: - NSSOC_LOGINF ("rong parmeter optname]=%d", optname); - nstack_set_errno (ENOPROTOOPT); - return -1; - } - return 0; + nsep_set_info_sleep_time(fdInf->fd, *(u32_t *) optval); /*no need to check null pointer */ + NSSOC_LOGINF("set sem wait option] g_sem_sleep_time=%u", + *(u32_t *) optval); + break; + case NSTACK_RD_MODE: + rd_opt = *(ns_int32 *) optval; + if (rd_opt < -1 || rd_opt >= nstack_get_module_num()) + { + NSSOC_LOGWAR("invail rd mode fd=%d, mode=%d", fdInf->fd, + rd_opt); + nstack_set_errno(EINVAL); + return -1; + } + fdInf->rd_opt = rd_opt; + NSSOC_LOGINF("set rd mode] mode=%d", rd_opt); + break; + default: + NSSOC_LOGINF("rong parmeter optname]=%d", optname); + nstack_set_errno(ENOPROTOOPT); + return -1; + } + return 0; } -int -nstack_option_get (nstack_fd_Inf * fdInf, int optname, const void *optval, - socklen_t * optlen) +int nstack_option_get(nstack_fd_Inf * fdInf, int optname, const void *optval, + socklen_t * optlen) { - if ((!optval) || (!optlen) || (optlen && (*optlen < sizeof (u32_t)))) + if ((!optval) || (!optlen) || (*optlen < sizeof(u32_t))) { - NSSOC_LOGINF ("rong parmeter optname]=%d", optname); - nstack_set_errno (EINVAL); - return -1; + NSSOC_LOGINF("rong parmeter optname]=%d", optname); + nstack_set_errno(EINVAL); + return -1; } - switch (optname) + switch (optname) { - case NSTACK_SEM_SLEEP: - *(long *) optval = nsep_get_infoSleepTime (fdInf->fd); - NSSOC_LOGINF ("get sem wait option] g_sem_sleep_time=%ld", - *(long *) optval); - break; - - default: - NSSOC_LOGINF ("rong parmeter optname]=%d", optname); - nstack_set_errno (ENOPROTOOPT); - return -1; + case NSTACK_SEM_SLEEP: + *(long *) optval = nsep_get_info_sleep_time(fdInf->fd); /*no need to check null pointer */ + NSSOC_LOGINF("get sem wait option] g_sem_sleep_time=%ld", + *(long *) optval); + break; + case NSTACK_RD_MODE: + *(ns_int32 *) optval = fdInf->rd_opt; + NSSOC_LOGINF("get rd mode] mode=%d", *(ns_int32 *) optval); + break; + default: + NSSOC_LOGINF("rong parmeter optname]=%d", optname); + nstack_set_errno(ENOPROTOOPT); + return -1; } - return 0; + return 0; } /* just use first rlfd to getsockopt, this may not what app really want.*/ -/* Currently, if getsockopt is successfull either in kernel or stack-x, the below API returns SUCCESS */ -int -nstack_getsockopt (int fd, int level, int optname, void *optval, - socklen_t * optlen) +/* Currently, if getsockopt is successfull either in kernel or lwip, the below API returns SUCCESS */ +int nstack_getsockopt(int fd, int level, int optname, void *optval, + socklen_t * optlen) { - nstack_fd_Inf *fdInf; - int tfd; - int ret = -1; - nstack_socket_ops *ops; + nstack_fd_Inf *fdInf; + int tfd; + int ret = -1; + nstack_socket_ops *ops; - NSTACK_INIT_CHECK_RET (getsockopt, fd, level, optname, optval, optlen); + NSTACK_INIT_CHECK_RET(getsockopt, fd, level, optname, optval, optlen); - NS_LOG_CTRL (LOG_CTRL_GETSOCKOPT, NSOCKET, "NSSOC", NSLOG_INF, - "(fd=%d, level=%d, optname=%d, optval=%p, optlen=%p) [Caller]", - fd, level, optname, optval, optlen); + NS_LOG_CTRL(LOG_CTRL_GETSOCKOPT, NSOCKET, "SOC", NSLOG_INF, + "fd=%d,level=%d,optname=%d,optval=%p,optlen=%p[Caller]", + fd, level, optname, optval, optlen); - if (fd < 0) + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d[return]", fd); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, getsockopt, fdInf, - (fd, level, optname, optval, optlen)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, getsockopt, fdInf, + (fd, level, optname, optval, optlen)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); - if ((NSTACK_SOCKOPT == level) && NSTACK_IS_FD_EPOLL_SOCKET (fdInf)) + if ((NSTACK_SOCKOPT == level) && + (NSTACK_IS_FD_EPOLL_SOCKET(fdInf) || NSTACK_RD_MODE == optname)) { - ret = nstack_option_get (fdInf, optname, optval, optlen); - UNLOCK_COMMON (fd, local_lock); - return ret; + ret = nstack_option_get(fdInf, optname, optval, optlen); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } - if (fdInf->ops) + if (fdInf->ops) { - tfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, getsockopt, - (tfd, level, optname, optval, optlen), ret); - NSSOC_LOGINF - ("fd=%d,module=%s,tfd=%d,level=%d,optname=%d,ret=%d [return]", fd, - nstack_get_module_name_by_idx (fdInf->rmidx), tfd, level, optname, - ret); - if (-1 == ret) + tfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, getsockopt, + (tfd, level, optname, optval, optlen), ret); + NSSOC_LOGINF + ("fd=%d,module=%s,tfd=%d,level=%d,optname=%d,ret=%d[return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), tfd, level, + optname, ret); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d [return]", fdInf->rmidx, - tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d[return]", fdInf->rmidx, + tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } - if (NULL != g_nstack_modules.defMod) + if (NULL != g_nstack_modules.defMod) { - tfd = nstack_get_protoFd (fdInf, nstack_defMod_inx ()); - if (tfd >= 0) + tfd = nstack_get_proto_fd(fdInf, nstack_defmod_inx()); + if (tfd >= 0) { - ops = nstack_def_ops (); - NSTACK_CAL_FUN (ops, getsockopt, - (tfd, level, optname, optval, optlen), ret); - NSSOC_LOGINF - ("fd=%d,module=%s:%d,level=%d,optname=%d,ret=%d [return]", fd, - nstack_defmod_name (), tfd, level, optname, ret); - if (-1 == ret) + ops = nstack_def_ops(); + NSTACK_CAL_FUN(ops, getsockopt, + (tfd, level, optname, optval, optlen), ret); + NSSOC_LOGINF + ("fd=%d,module=%s:%d,level=%d,optname=%d,ret=%d[return]", fd, + nstack_defmod_name(), tfd, level, optname, ret); + if ((-1 == ret) + && (nstack_defmod_inx() != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d [return]", - nstack_defMod_inx (), tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d[return]", + nstack_defmod_inx(), tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } } - nstack_set_errno (ENOTSOCK); - NSSOC_LOGINF ("fd=%d,ret=%d [Return]", fd, ret); - UNLOCK_COMMON (fd, local_lock); - return ret; + nstack_set_errno(ENOTSOCK); + NSSOC_LOGINF("fd=%d,ret=%d [Return]", fd, ret); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } -/* all rlfd need setsockopt, set opt failed still can Establish connection. so we not care suc/fail */ -/* Currently, if setsockopt is successfull either in kernel or stack-x, the below API returns SUCCESS */ -int -nstack_setsockopt (int fd, int level, int optname, const void *optval, - socklen_t optlen) +/* all rlfd need setsockopt, set opt failed still can Estblsh connection. so we not care suc/fail */ +/* Currently, if setsockopt is successfull either in kernel or lwip, the below API returns SUCCESS */ +int nstack_setsockopt(int fd, int level, int optname, const void *optval, + socklen_t optlen) { - nstack_fd_Inf *fdInf; - int ret = -1; - nstack_socket_ops *ops; - int itfd; - int modInx = 0; - int curRet = -1; - int lerror = 0; - int flag = 0; - - NSTACK_INIT_CHECK_RET (setsockopt, fd, level, optname, optval, optlen); - - NSSOC_LOGINF - ("(fd=%d, level=%d, optname=%d, optval=%p, optlen=%u) [Caller]", fd, - level, optname, optval, optlen); - - if (fd < 0) - { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d [return]", fd); - return -1; - } - - NSTACK_FD_LINUX_CHECK (fd, setsockopt, fdInf, - (fd, level, optname, optval, optlen)); - - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); - - if ((NSTACK_SOCKOPT == level) && NSTACK_IS_FD_EPOLL_SOCKET (fdInf)) - { - ret = nstack_option_set (fdInf, optname, optval, optlen); - UNLOCK_COMMON (fd, local_lock); - return ret; - } - - if (fdInf->ops) - { - itfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, setsockopt, - (itfd, level, optname, optval, optlen), ret); - NSSOC_LOGINF - ("fd=%d,module=%s,tfd=%d,level=%d,optname=%d,ret=%d [return]", fd, - nstack_get_module_name_by_idx (fdInf->rmidx), itfd, level, optname, - ret); - if (-1 == ret) - { - NSSOC_LOGERR ("return fail]module=%d,fd=%d [return]", fdInf->rmidx, - itfd); - } - UNLOCK_COMMON (fd, local_lock); - return ret; - } - nstack_each_modOps (modInx, ops) - { - itfd = nstack_get_protoFd (fdInf, modInx); - if (-1 == itfd) - { - continue; - } - flag = 1; - NSTACK_CAL_FUN (ops, setsockopt, (itfd, level, optname, optval, optlen), - curRet); - NSSOC_LOGDBG ("fd=%d,module=%s,tfd=%d,level=%d,optname=%d,ret=%d", fd, - nstack_get_module_name_by_idx (modInx), itfd, level, - optname, curRet); - if (modInx == nstack_get_fix_mid ()) - { - ret = curRet; - /* errno is thread safe, but stack-x is not, so save it first */ - lerror = errno; - } - } - /* errno is thread safe, but stack-x is not, so save it first begin */ - /*if all fd of stack is -1, the input fd maybe invalid */ - if (0 == flag) - { - nstack_set_errno (EBADF); - } - /*if linux return fail, and error is none zero, just reset it again */ - if ((lerror != 0) && (ns_success != ret)) - { - nstack_set_errno (lerror); - } - /* errno is thread safe, but stack-x is not, so save it first end */ - NSSOC_LOGINF ("fd=%d,ret=%d [Return]", fd, ret); - UNLOCK_COMMON (fd, local_lock); - return ret; + nstack_fd_Inf *fdInf; + int ret = -1; + nstack_socket_ops *ops; + int itfd; + int modInx = 0; + int curRet = -1; + int lerror = 0; + int flag = 0; + + NSTACK_INIT_CHECK_RET(setsockopt, fd, level, optname, optval, optlen); + + NSSOC_LOGINF("fd=%d,level=%d,optname=%d,optval=%p,optlen=%u[Caller]", + fd, level, optname, optval, optlen); + + if (fd < 0) + { + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d[return]", fd); + return -1; + } + + NSTACK_FD_LINUX_CHECK_RETURN(fd, setsockopt, fdInf, + (fd, level, optname, optval, optlen)); + + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); + + if ((NSTACK_SOCKOPT == level) && + (NSTACK_IS_FD_EPOLL_SOCKET(fdInf) || NSTACK_RD_MODE == optname)) + { + ret = nstack_option_set(fdInf, optname, optval, optlen); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; + } + + if (fdInf->ops) + { + itfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, setsockopt, + (itfd, level, optname, optval, optlen), ret); + NSSOC_LOGINF + ("fd=%d,module=%s,tfd=%d,level=%d,optname=%d,ret=%d[return]", fd, + nstack_get_module_name_by_idx(fdInf->rmidx), itfd, level, + optname, ret); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) + { + NSSOC_LOGERR("return fail]mudle=%d,fd=%d[return]", fdInf->rmidx, + itfd); + } + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; + } + nstack_each_mod_ops(modInx, ops) + { + itfd = nstack_get_proto_fd(fdInf, modInx); + if (-1 == itfd) + { + continue; + } + flag = 1; + NSTACK_CAL_FUN(ops, setsockopt, + (itfd, level, optname, optval, optlen), curRet); + NSSOC_LOGDBG("fd=%d,module=%s,tfd=%d,level=%d,optname=%d,ret=%d", fd, + nstack_get_module_name_by_idx(modInx), itfd, level, + optname, curRet); + if (modInx == nstack_get_linux_mid()) + { + ret = curRet; + /*errno is thread safe, but stackpool is not, so save it first */ + lerror = errno; + } + } + /* errno is thread safe, but stackpool is not, so save it first */ + /*if all fd of stack is -1, the input fd maybe invalid */ + if (0 == flag) + { + nstack_set_errno(EBADF); + } + /*if linux return fail, and error is none zero, just reset it again */ + if ((lerror != 0) && (ns_success != ret)) + { + nstack_set_errno(lerror); + } + /*errno is thread safe, but stackpool is not, so save it first */ + NSSOC_LOGINF("fd=%d,ret=%d[Return]", fd, ret); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } -int -nstack_ioctl (int fd, unsigned long request, unsigned long argp) +int nstack_ioctl(int fd, unsigned long request, unsigned long argp) { - nstack_fd_Inf *fdInf; - int ret = -1; - nstack_socket_ops *ops; - int tfd; - int modInx = 0; - int curRet = -1; - int lerror = 0; - int flag = 0; + nstack_fd_Inf *fdInf; + int ret = -1; + nstack_socket_ops *ops; + int tfd; + int modInx = 0; + int curRet = -1; + int lerror = 0; + int flag = 0; - NSTACK_INIT_CHECK_RET (ioctl, fd, request, argp); + NSTACK_INIT_CHECK_RET(ioctl, fd, request, argp); - NSSOC_LOGINF ("(fd=%d, request=%lu) [Caller]", fd, request); - if (fd < 0) + NSSOC_LOGINF("fd=%d,request=%lu[Caller]", fd, request); + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d[return]", fd); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, ioctl, fdInf, (fd, request, argp)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, ioctl, fdInf, (fd, request, argp)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); - if (fdInf->ops) + LOCK_COMMON(fd, fdInf, local_lock); + if (fdInf->ops) { - tfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, ioctl, (tfd, request, argp), ret); - NSSOC_LOGINF ("fd=%d,module=%s,rlfd=%d,argp=0x%x,ret=%d [return]", - fd, nstack_get_module_name_by_idx (fdInf->rmidx), - fdInf->rlfd, argp, ret); - if (-1 == ret) + tfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, ioctl, (tfd, request, argp), ret); + NSSOC_LOGINF("fd=%d,module=%s,rlfd=%d,argp=0x%x,ret=%d[return]", + fd, nstack_get_module_name_by_idx(fdInf->rmidx), + fdInf->rlfd, argp, ret); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d [return]", fdInf->rmidx, - tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d[return]", fdInf->rmidx, + tfd); } - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } - nstack_each_modOps (modInx, ops) - { - tfd = nstack_get_protoFd (fdInf, modInx); - if (-1 == tfd) - { - continue; - } - flag = 1; + nstack_each_mod_ops(modInx, ops) + { + tfd = nstack_get_proto_fd(fdInf, modInx); + if (-1 == tfd) + { + continue; + } + flag = 1; - NSTACK_CAL_FUN (ops, ioctl, (tfd, request, argp), curRet); - NSSOC_LOGINF ("fd=%d,module=%s,tfd=%d,argp=0x%x,ret=%d ", - fd, nstack_get_module_name_by_idx (modInx), tfd, argp, - curRet); - if (modInx == nstack_get_fix_mid ()) - { - ret = curRet; - /* errno is thread safe, but stack-x is not, so save it first */ - lerror = errno; - } - } - /* errno is thread safe, but stack-x is not, so save it first */ - if (0 == flag) + NSTACK_CAL_FUN(ops, ioctl, (tfd, request, argp), curRet); + NSSOC_LOGINF("fd=%d,module=%s,tfd=%d,argp=0x%x,ret=%d ", + fd, nstack_get_module_name_by_idx(modInx), tfd, argp, + curRet); + if (modInx == nstack_get_linux_mid()) + { + ret = curRet; + /*errno is thread safe, but stackpool is not, so save it first */ + lerror = errno; + } + } + /*errno is thread safe, but stackpool is not, so save it first */ + if (0 == flag) { - nstack_set_errno (EBADF); + nstack_set_errno(EBADF); } - if ((0 != lerror) && (ns_success != ret)) + if ((0 != lerror) && (ns_success != ret)) { - nstack_set_errno (lerror); + nstack_set_errno(lerror); } + /*errno is thread safe, but stackpool is not, so save it first */ - NSSOC_LOGINF ("fd=%d,ret=%d [return]", fd, ret); + NSSOC_LOGINF("fd=%d,ret=%d[return]", fd, ret); - UNLOCK_COMMON (fd, local_lock); - return ret; + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } -int -nstack_fcntl (int fd, int cmd, unsigned long argp) +int nstack_fcntl(int fd, int cmd, unsigned long argp) { - nstack_fd_Inf *fdInf; - nstack_socket_ops *ops = NULL; - int ret = -1; - int noProOpt = 0; - int tfd; - int modInx = 0; - int curRet = -1; - int lerror = 0; - int flag = 0; + nstack_fd_Inf *fdInf; + nstack_socket_ops *ops = NULL; + int ret = -1; + int noProOpt = 0; + int tfd; + int modInx = 0; + int curRet = -1; + int lerror = 0; + int flag = 0; - NSTACK_INIT_CHECK_RET (fcntl, fd, cmd, argp); + NSTACK_INIT_CHECK_RET(fcntl, fd, cmd, argp); - NSSOC_LOGINF ("(fd=%d, cmd=%d) [Caller]", fd, cmd); - if (fd < 0) + NSSOC_LOGINF("fd=%d,cmd=%d[Caller]", fd, cmd); + if (fd < 0) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("invalid input]fd=%d [return]", fd); - return -1; + nstack_set_errno(EBADF); + NSSOC_LOGERR("invalid input]fd=%d[return]", fd); + return -1; } - NSTACK_FD_LINUX_CHECK (fd, fcntl, fdInf, (fd, cmd, argp)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, fcntl, fdInf, (fd, cmd, argp)); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_COMMON (fd, fdInf, local_lock); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_COMMON(fd, fdInf, local_lock); - /*have already bind */ - if (fdInf->ops) + /*have already bind */ + if (fdInf->ops) { - tfd = fdInf->rlfd; - NSTACK_CAL_FUN (fdInf->ops, fcntl, (tfd, cmd, argp), ret); - NSSOC_LOGINF ("fd=%d,cmd=%d,mod=%s,tfd=%d,argp=0x%x,ret=%d", - fd, cmd, nstack_get_module_name_by_idx (fdInf->rmidx), - tfd, argp, ret); - if (-1 == ret) + tfd = fdInf->rlfd; + NSTACK_CAL_FUN(fdInf->ops, fcntl, (tfd, cmd, argp), ret); + NSSOC_LOGINF("fd=%d,cmd=%d,mod=%s,tfd=%d,argp=0x%x,ret=%d", + fd, cmd, nstack_get_module_name_by_idx(fdInf->rmidx), + tfd, argp, ret); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d", fdInf->rmidx, tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d", fdInf->rmidx, tfd); } } - else + else { - /*set cmd call all module, and return just linux */ - if (F_SETFL == cmd) + /*set cmd call all module, and return just linux */ + if (F_SETFL == cmd) { - nstack_each_modOps (modInx, ops) - { - tfd = nstack_get_protoFd (fdInf, modInx); - if (-1 == tfd) - { - continue; - } - flag = 1; - noProOpt = 0; - NSTACK_CAL_FUN (ops, fcntl, (tfd, cmd, argp), curRet); - NSSOC_LOGINF ("fd=%d,module=%s,tfd=%d,argp=0x%x,ret=%d ", - fd, nstack_get_module_name_by_idx (modInx), tfd, - argp, curRet); - if (modInx == nstack_get_fix_mid ()) - { - ret = curRet; - lerror = errno; - } - } - /* errno is thread safe, but stack-x is not, so save it first */ - if (0 == flag) + nstack_each_mod_ops(modInx, ops) + { + tfd = nstack_get_proto_fd(fdInf, modInx); + if (-1 == tfd) + { + continue; + } + flag = 1; + noProOpt = 0; + NSTACK_CAL_FUN(ops, fcntl, (tfd, cmd, argp), curRet); + NSSOC_LOGINF("fd=%d,module=%s,tfd=%d,argp=0x%x,ret=%d ", + fd, nstack_get_module_name_by_idx(modInx), tfd, + argp, curRet); + if (modInx == nstack_get_linux_mid()) + { + ret = curRet; + lerror = errno; + } + } + /*errno is thread safe, but stackpool is not, so save it first */ + if (0 == flag) { - nstack_set_errno (EBADF); + nstack_set_errno(EBADF); } - if ((0 != lerror) && (ns_success != ret)) + if ((0 != lerror) && (ns_success != ret)) { - nstack_set_errno (lerror); + nstack_set_errno(lerror); } + /*errno is thread safe, but stackpool is not, so save it first */ } /*other cmd call default */ - else if (g_nstack_modules.defMod) + else if (g_nstack_modules.defMod) { - tfd = nstack_get_protoFd (fdInf, g_nstack_modules.defMod->modInx); - if (tfd >= 0) + tfd = nstack_get_proto_fd(fdInf, g_nstack_modules.defMod->modInx); + if (tfd >= 0) { - ops = nstack_def_ops (); - NSTACK_CAL_FUN (ops, fcntl, (tfd, cmd, argp), ret); - NSSOC_LOGINF ("fd=%d,cmd=%d,mod=%s,tfd=%d,argp=0x%x,ret=%d", - fd, cmd, g_nstack_modules.defMod->modulename, tfd, - argp, ret); - if (-1 == ret) + ops = nstack_def_ops(); + NSTACK_CAL_FUN(ops, fcntl, (tfd, cmd, argp), ret); + NSSOC_LOGINF("fd=%d,cmd=%d,mod=%s,tfd=%d,argp=0x%x,ret=%d", + fd, cmd, g_nstack_modules.defMod->modulename, + tfd, argp, ret); + if ((-1 == ret) && (fdInf->rmidx != nstack_get_linux_mid())) { - NSSOC_LOGERR ("return fail]module=%d,fd=%d", - g_nstack_modules.defMod->modInx, tfd); + NSSOC_LOGERR("return fail]mudle=%d,fd=%d", + g_nstack_modules.defMod->modInx, tfd); } } - else + else { - noProOpt = 1; + noProOpt = 1; } } - else + else { - noProOpt = 1; + noProOpt = 1; } } - if (noProOpt) + if (noProOpt) { - nstack_set_errno (EBADF); - NSSOC_LOGINF ("fd=%d,ret=%d", fd, ret); + nstack_set_errno(EBADF); + NSSOC_LOGINF("fd=%d,ret=%d", fd, ret); } - NSSOC_LOGINF ("fd=%d,cmd=%d,ret=%d [return]", fd, cmd, ret); - UNLOCK_COMMON (fd, local_lock); - return ret; + NSSOC_LOGINF("fd=%d,cmd=%d,ret=%d[return]", fd, cmd, ret); + UNLOCK_COMMON(fd, fdInf, local_lock); + return ret; } -/***************************************************************************** -* Prototype : nstack_select -* Description : nstack_select -* Input : int nfds -* fd_set *readfds -* fd_set *writefds -* fd_set *exceptfds -* struct timeval *timeout -* Output : None -* Return Value : int -* Calls : -* Called By : -*****************************************************************************/ -int -nstack_select (int nfds, fd_set * readfds, fd_set * writefds, - fd_set * exceptfds, struct timeval *timeout) +int nstack_select(int nfds, fd_set * readfds, fd_set * writefds, + fd_set * exceptfds, struct timeval *timeout) { - int ret = -1; - - struct select_entry *entry = NULL; - struct select_module_info *select_module = get_select_module (); - u64_t msec; + struct select_module_info *select_module = get_select_module(); - int i; + NSTACK_INIT_CHECK_RET(select, nfds, readfds, writefds, exceptfds, + timeout); - NSTACK_INIT_CHECK_RET (select, nfds, readfds, writefds, exceptfds, timeout); - - if ((nfds > __FD_SETSIZE) || (nfds < 0) - || ((timeout) && ((timeout->tv_sec < 0) || (timeout->tv_usec < 0)))) + if (NFDS_NOT_VALID(nfds) || TIMEVAL_NOT_VALID(timeout)) { - NSSOC_LOGERR ("paremeter of nfds or timeout are no correct.]nfds = %d \ - sec = %ld usec = %ld", nfds, timeout->tv_sec, timeout->tv_usec); - errno = EINVAL; - return -1; + NSSOC_LOGERR("paremeter of nfds or timeout are no correct]nfds=%d \ + sec=%ld usec=%ld", nfds, timeout->tv_sec, timeout->tv_usec); + errno = EINVAL; + return -1; } - for (i = 0; i < nfds; i++) - { - if ((readfds) && (FD_ISSET (i, readfds))) - { - NSSOC_LOGDBG ("input readfd set %d", i); - } + print_select_dbg(nfds, readfds, writefds, exceptfds); - if ((writefds) && (FD_ISSET (i, writefds))) - { - NSSOC_LOGDBG ("input writefd set %d", i); - } - if ((exceptfds) && (FD_ISSET (i, exceptfds))) - { - NSSOC_LOGDBG ("input exceptfds set %d", i); - } - } - - /*check the module had regist or not */ - if (TRUE != NSTACK_SELECT_LINUX_CHECK ()) + /*check the module had regist or not */ + if (TRUE != NSTACK_SELECT_LINUX_CHECK()) { - return nsfw_base_select (nfds, readfds, writefds, exceptfds, timeout); + return nsfw_base_select(nfds, readfds, writefds, exceptfds, timeout); } - /*nstack select not support timer function and not check nfds so calling default select */ - if ((nfds <= 0) - || ((NULL == readfds) && (NULL == writefds) && (NULL == exceptfds))) + /*nstack select not support timer function and not check nfds so calling dufault select */ + if (is_select_used_as_timer(nfds, readfds, writefds, exceptfds)) { - if ((select_module) && (select_module->default_fun)) + if ((select_module) && (select_module->default_fun)) { - return select_module->default_fun (nfds, readfds, writefds, - exceptfds, timeout); + return select_module->default_fun(nfds, readfds, writefds, + exceptfds, timeout); } - else + else { - return nsfw_base_select (nfds, readfds, writefds, exceptfds, - timeout); + return nsfw_base_select(nfds, readfds, writefds, exceptfds, + timeout); } } - entry = (struct select_entry *) select_alloc (sizeof (struct select_entry)); - if (NULL == entry) - { - errno = ENOMEM; - NSSOC_LOGERR ("select entry alloc failed"); - goto err_return; - } + return nstack_select_processing(nfds, readfds, writefds, exceptfds, + timeout); - /* fix dead-code type Codex issue */ - /*split select fd to each modules fd and save to entry */ - (void) select_cb_split_by_mod (nfds, readfds, writefds, exceptfds, entry); +} - /*if all fd in default module we just calling it */ - if (entry->info.set_num <= 1) - { +/* epfd?fd maybe is from kernel or stackpool,should take care */ +int nstack_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + int ret = ns_fail; + struct eventpoll *ep = NULL; + nstack_fd_Inf *epInf; + struct epoll_event ep_event = { 0 }; + struct epitem *epi = NULL; - /*adapte linux */ - if ((select_module) - && (entry->info.index == select_module->default_mod)) - { - if (select_module->default_fun) - { - ret = - select_module->default_fun (nfds, readfds, writefds, - exceptfds, timeout); - } - else - { - ret = - nsfw_base_select (nfds, readfds, writefds, exceptfds, - timeout); - } - goto err_return; - } + NSTACK_INIT_CHECK_RET(epoll_ctl, epfd, op, fd, event); + + NSSOC_LOGINF("epfd=%d,op=%d,fd=%d,event=%p[Caller]", epfd, op, fd, event); + if (event) + { + NSSOC_LOGINF("event->data.fd=%d,event->events=%u", event->data.fd, + event->events); } - /*checking if event ready or not */ - if (FALSE == select_scan (entry)) + NSTACK_FD_LINUX_CHECK_RETURN(epfd, epoll_ctl, epInf, + (epfd, op, fd, event)); + + nstack_fd_local_lock_info_t *epoll_local_lock = &epInf->local_lock; + LOCK_EPOLL(epfd, epInf, epoll_local_lock); + nstack_fd_local_lock_info_t *local_lock = get_fd_local_lock_info(fd); + LOCK_EPOLL_CTRL_RETURN(fd, local_lock, epfd, epoll_local_lock); + + if (!NSTACK_IS_FD_EPOLL_SOCKET(epInf) || fd == epfd) /* `man epoll_ctl` tells me to do this check :) */ { - NSSOC_LOGERR ("select scan failed"); - goto err_return; + NSSOC_LOGWAR("epfd=%d is not a epoll fd[return]", epfd); + errno = EINVAL; + goto err_return; } - if (entry->ready.readyset != 0) + if (!nstack_is_nstack_sk(fd)) { - goto scan_return; + NSSOC_LOGWAR("epfd=%d ,fd %d is not a supported [return]", epfd, fd); + errno = EBADF; + goto err_return; } - if ((timeout) && (timeout->tv_sec == 0) && (timeout->tv_usec == 0)) + nsep_epollInfo_t *epInfo = nsep_get_info_by_sock(epfd); + if (NULL == epInfo) { - goto scan_return; + NSSOC_LOGWAR("epInfo of epfd=%d is NULL[return]", epfd); + errno = EINVAL; + goto err_return; } - if (FALSE == select_add_cb (entry)) + ep = SHMEM_ADDR_SHTOL(epInfo->ep); + if (NULL == ep) { - errno = ENOMEM; - NSSOC_LOGERR ("select entry add failed"); - goto err_return; + NSSOC_LOGWAR("ep of epfd=%d is NULL[return]", epfd); + errno = EINVAL; + goto err_return; } - if (NULL == timeout) + if (NULL != event) { - select_sem_wait (&entry->sem); + ep_event.data = event->data; + ep_event.events = event->events; } - else + else { - u64_t time_cost; - if (nstack_timeval2msec (timeout, &msec)) + if (op != EPOLL_CTL_DEL) { - nstack_set_errno (EINVAL); - goto err_return; - } - time_cost = nstack_sem_timedwait (&entry->sem, msec); - if (time_cost >= msec) - { - timeout->tv_sec = 0; - timeout->tv_usec = 0; - } - else if (time_cost > 0) - { - msec = msec - time_cost; - timeout->tv_sec = msec / 1000; - timeout->tv_usec = (msec % 1000) * 1000; + NSSOC_LOGWAR("events epfd=%d is NULL[return]", epfd); + errno = EFAULT; + goto err_return; } } - select_rm_cb (entry); + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->sem)); /*do not need return value */ -scan_return: - if (readfds) + epi = nsep_find_ep(ep, fd); + switch (op) { - *readfds = entry->ready.readset; - } - if (writefds) - { - *writefds = entry->ready.writeset; - } - if (exceptfds) - { - *exceptfds = entry->ready.exceptset; - } + case EPOLL_CTL_ADD: + if (!epi) + { - ret = entry->ready.readyset; - if (ret < 0) - { - errno = entry->ready.select_errno; - } + ep_event.events |= (EPOLLERR | EPOLLHUP); // Check `man epoll_ctl` if you don't understand , smile :) -err_return: - if (entry) - { - select_free ((char *) entry); - } - NSSOC_LOGDBG - ("(nfds=%d,readfds=%p,writefds=%p,exceptfds=%p,timeout=%p),ret=%d errno = %d", - nfds, readfds, writefds, exceptfds, timeout, ret, errno); - return ret; -} + dmm_read_lock(get_fork_lock()); /* to ensure that there is no fd to create and close when fork. */ + ret = nsep_epctl_add(ep, epInfo, fd, &ep_event); + dmm_read_unlock(get_fork_lock()); + } + else + { + NSSOC_LOGWAR("fd already in eventpoll"); + errno = EEXIST; + ret = -1; + } + break; + case EPOLL_CTL_DEL: + if (epi) + { + dmm_read_lock(get_fork_lock()); + ret = nsep_epctl_del(ep, epi); + dmm_read_unlock(get_fork_lock()); + } + else + { + NSSOC_LOGWAR("fd not registed before"); + errno = ENOENT; + ret = -1; + } + break; + case EPOLL_CTL_MOD: + if (epi) + { -/* epfd?fd maybe is from kernel or stack-x,should take care */ -int -nstack_epoll_ctl (int epfd, int op, int fd, struct epoll_event *event) -{ - int ret = ns_fail; - struct eventpoll *ep = NULL; - nstack_fd_Inf *epInf; - struct epoll_event ep_event = { 0 }; - struct epitem *epi = NULL; + ep_event.events |= (EPOLLERR | EPOLLHUP); // Look up ? - NSTACK_INIT_CHECK_RET (epoll_ctl, epfd, op, fd, event); + ret = + nsep_epctl_mod(ep, nsep_get_info_by_sock(fd), epi, + &ep_event); + } + else + { + NSSOC_LOGWAR("fd not registed before"); + errno = ENOENT; + ret = -1; + } + break; + default: + NSSOC_LOGERR("epfd=%d,fd=%d,opt=%d not supported", epfd, fd, op); + errno = EINVAL; + ret = -1; + } - NSSOC_LOGINF ("(epfd=%d, op=%d, fd=%d, event=%p) [Caller]", epfd, op, fd, - event); - if (event) - NSSOC_LOGINF ("event->data.fd=%d,event->events=%u", event->data.fd, - event->events); + dmm_spin_unlock((dmm_spinlock_t *) (&ep->sem)); + NSSOC_LOGINF("epfd=%d,op=%d,fd=%d,ret=%d[return]", epfd, op, fd, ret); - NSTACK_FD_LINUX_CHECK (epfd, epoll_ctl, epInf, (epfd, op, fd, event)); + err_return: + UNLOCK_EPOLL_CTRL(fd, local_lock); + UNLOCK_EPOLL(epfd, epoll_local_lock); + return ret; +} - nstack_fd_local_lock_info_t *epoll_local_lock = &epInf->local_lock; - LOCK_EPOLL (epfd, epInf, epoll_local_lock); - nstack_fd_local_lock_info_t *local_lock = get_fd_local_lock_info (fd); - LOCK_EPOLL_CTRL (fd, local_lock, epfd, epoll_local_lock); +int nstack_epoll_create(int size) +{ + nstack_fd_Inf *fdInf = NULL; + struct eventpoll *ep = NULL; + struct spl_conn_pool *ep_conn = NULL; + int epfd = -1; - if (!NSTACK_IS_FD_EPOLL_SOCKET (epInf) || fd == epfd) /* `man epoll_ctl` tells me to do this check :) */ - { - NSSOC_LOGWAR ("epfd=%d is not a epoll fd [return]", epfd); - errno = EINVAL; - goto err_return; - } + NSTACK_INIT_CHECK_RET(epoll_create, size); + NSSOC_LOGINF("size=%d[Caller]", size); - if (!nstack_is_nstack_sk (fd)) + if (size <= 0) { - NSSOC_LOGWAR ("epfd=%d ,fd %d is not a supported [return]", epfd, fd); - errno = EBADF; - goto err_return; + errno = EINVAL; + NSSOC_LOGERR("invalid input,param]size=%d[return]", size); + return -1; } +#ifdef KERNEL_FD_SUPPORT + epfd = nsfw_base_epoll_create(size); - nsep_epollInfo_t *epInfo = nsep_get_infoBySock (epfd); - if (NULL == epInfo) + if (!nstack_is_nstack_sk(epfd)) { - NSSOC_LOGWAR ("epInfo of epfd=%d is NULL [return]", epfd); - errno = EINVAL; - goto err_return; + nsfw_base_close(epfd); /*do not need return value */ + NSSOC_LOGERR("kernel fd alloced is too larger]kernel_fd=%d[return]", + epfd); + errno = EMFILE; + return -1; } - ep = ADDR_SHTOL (epInfo->ep); - if (NULL == ep) + nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info(epfd); + LOCK_FOR_EP(lock_info); + fdInf = nstack_lk_fd_alloc_with_kernel(epfd); +#else + fdInf = nstack_lk_fd_alloc_without_kernel(); +#endif + if (NULL == fdInf) { - NSSOC_LOGWAR ("ep of epfd=%d is NULL [return]", epfd); - errno = EINVAL; - goto err_return; + NSSOC_LOGERR("create fdInf fail[return]"); + errno = ENOMEM; +#ifdef KERNEL_FD_SUPPORT + nsfw_base_close(epfd); /*do not need return value */ + UNLOCK_FOR_EP(lock_info); +#endif + return -1; } - if (NULL != event) - { - ep_event.data = event->data; - ep_event.events = event->events; - } - else - { - if (op != EPOLL_CTL_DEL) - { - NSSOC_LOGWAR ("events epfd=%d is NULL [return]", epfd); - errno = EFAULT; - goto err_return; - } - } +#ifndef KERNEL_FD_SUPPORT + epfd = fdInf->fd; + nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info(epfd); + LOCK_FOR_EP(lock_info); +#endif - sys_arch_lock_with_pid (&ep->sem); + /* here can't check return value, because if daemon-stack is old version, then here will fail, it is normal scenario */ + (void) nsep_alloc_ep_spl_conn_ring(&ep_conn); - epi = nsep_find_ep (ep, fd); - switch (op) + int pesudoEpIdx = nsep_alloc_eventpoll(&ep); + if (pesudoEpIdx < 0) { - case EPOLL_CTL_ADD: - if (!epi) - { - ep_event.events |= (EPOLLERR | EPOLLHUP); // Check `man epoll_ctl` if you don't understand , smile :) - common_mem_rwlock_read_lock (get_fork_lock ()); /* to ensure that there is no fd to create and close when fork. added by tongshaojun t00391048 */ - ret = nsep_epctl_add (ep, fd, &ep_event); - common_mem_rwlock_read_unlock (get_fork_lock ()); - } - else - { - NSSOC_LOGWAR ("fd already in eventpoll"); - errno = EEXIST; - ret = -1; - } - break; - case EPOLL_CTL_DEL: - if (epi) - { - common_mem_rwlock_read_lock (get_fork_lock ()); - ret = nsep_epctl_del (ep, epi); - common_mem_rwlock_read_unlock (get_fork_lock ()); - } - else - { - NSSOC_LOGWAR ("fd not registered before"); - errno = ENOENT; - ret = -1; - } - break; - case EPOLL_CTL_MOD: - if (epi) - { - ep_event.events |= (EPOLLERR | EPOLLHUP); // Look up ? - ret = nsep_epctl_mod (ep, nsep_get_infoBySock (fd), epi, &ep_event); - } - else - { - NSSOC_LOGWAR ("fd not registered before"); - errno = ENOENT; - ret = -1; - } - break; - default: - NSSOC_LOGERR ("epfd=%d,fd=%d,opt=%d not supported", epfd, fd, op); - errno = EINVAL; - ret = -1; + nsep_free_info_with_sock(epfd); /*do not need return value */ + NSSOC_LOGERR("Alloc eventpoll fail[return]"); +#ifdef KERNEL_FD_SUPPORT + nstack_fd_free_with_kernel(fdInf); /*do not need return value */ +#else + nstack_fd_free(fdInf); +#endif + (void) nsep_free_ep_spl_conn_ring(ep_conn); + errno = ENOMEM; + UNLOCK_FOR_EP(lock_info); + return -1; } - sys_sem_s_signal (&ep->sem); - NSSOC_LOGINF ("epfd=%d,op=%d,fd=%d,ret=%d [return]", epfd, op, fd, ret); + ep->epfd = epfd; + nsep_set_info_ep_resource(epfd, ep, ep_conn); + NSTACK_SET_FD_EPOLL_SOCKET(fdInf); -err_return: - UNLOCK_EPOLL_CTRL (fd, local_lock); - UNLOCK_EPOLL (epfd, epoll_local_lock); - return ret; + NSSOC_LOGINF("fd=%d[return]", epfd); + set_fd_status_lock_fork(epfd, FD_OPEN); + UNLOCK_FOR_EP(lock_info); + return epfd; } -int -nstack_epoll_create (int size) +int nstack_epoll_wait(int epfd, struct epoll_event *events, int maxevents, + int timeout) { - nstack_fd_Inf *fdInf = NULL; - struct eventpoll *ep = NULL; - int epfd = -1; - int modInx = 0; - int tfd = 0; - nstack_socket_ops *ops; - int ret = 0; + nstack_fd_Inf *fdInf = NULL; + nsep_epollInfo_t *epInfo = NULL; + struct eventpoll *ep = NULL; + struct spl_conn_pool *ep_conn = NULL; + int evt = 0; + int ret = 0; + int evt_ns = 0; - NSTACK_INIT_CHECK_RET (epoll_create, size); + NSTACK_INIT_CHECK_RET(epoll_wait, epfd, events, maxevents, timeout); - NSSOC_LOGINF ("(size=%d) [Caller]", size); + NSTACK_FD_LINUX_CHECK_RETURN(epfd, epoll_wait, fdInf, + (epfd, events, maxevents, timeout)); - if (size <= 0) + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_EPOLL(epfd, fdInf, local_lock); + + if (!NSTACK_IS_FD_EPOLL_SOCKET(fdInf)) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("invalid input,param]size=%d [return]", size); - return -1; + NSSOC_LOGWAR("epfd=%d is not a epoll fd", epfd); + errno = EINVAL; + UNLOCK_EPOLL(epfd, local_lock); + return -1; } - /*create a epfd */ - if (nstack_fix_mid_ops ()->pfepoll_create) + /* should check input paramter's validity */ + if (NULL == events) { - epfd = nstack_fix_mid_ops ()->pfepoll_create (size); + NSSOC_LOGWAR("events is NULL"); + errno = EINVAL; + UNLOCK_EPOLL(epfd, local_lock); + return -1; } - else + + epInfo = nsep_get_info_by_sock(epfd); + if (NULL == epInfo) { - /*if not surport epfd create, just alloc a fd */ - if (nstack_extern_deal (nstack_get_fix_mid ()).stack_alloc_fd) - { - epfd = nstack_extern_deal (nstack_get_fix_mid ()).stack_alloc_fd (); - } - else - { - nstack_set_errno (ENOSYS); - NSSOC_LOGERR ("not surport epoll create]size=%d [return]", size); - return -1; - } + NSSOC_LOGWAR("epInfo is NULL]epinfo=%p,epfd=%d", epInfo, epfd); + errno = EINVAL; + UNLOCK_EPOLL(epfd, local_lock); + return -1; } - if (!nstack_is_nstack_sk (epfd)) + + ep = SHMEM_ADDR_SHTOL(epInfo->ep); + if (NULL == ep) { - if (epfd >= 0) - { - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (epfd), ret); - } - NSSOC_LOGERR ("kernel fd alloced is too larger]kernel_fd=%d [return]", - epfd); - nstack_set_errno (EMFILE); - return -1; + NSSOC_LOGWAR("fdInf->ep is NULL]epinfo=%p,epfd=%d", epInfo, epfd); + errno = EINVAL; + UNLOCK_EPOLL(epfd, local_lock); + return -1; } - nstack_fd_local_lock_info_t *lock_info = get_fd_local_lock_info (epfd); - LOCK_FOR_EP (lock_info); - fdInf = nstack_lk_fd_alloc_with_kernel (epfd); - if (NULL == fdInf) + if (maxevents <= 0) { - NSSOC_LOGERR ("create fdInf fail [return]"); - nstack_set_errno (ENOMEM); - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (epfd), ret); - UNLOCK_FOR_EP (lock_info); - return -1; + NSSOC_LOGWAR("maxevent less than zero]maxevents=%d", maxevents); + errno = EINVAL; + UNLOCK_EPOLL(epfd, local_lock); + return -1; } - if (nsep_alloc_eventpoll (&ep)) + NSTACK_GET_SYS_TICK(&ep->epoll_wait_tick); + ep->epoll_wait_pending = 1; + /* only if this ep is forked before, then set to 1 */ + if (epInfo->pidinfo.pid_used_size > 1) { - nsep_free_infoWithSock (epfd); - NSSOC_LOGERR ("Alloc eventpoll fail [return]"); - nstack_fd_free_with_kernel (fdInf); - nstack_set_errno (ENOMEM); - UNLOCK_FOR_EP (lock_info); - return -1; + ep->epoll_fork_flag = 1; } - ep->epfd = epfd; - nsep_set_infoEp (epfd, ep); - NSTACK_SET_FD_EPOLL_SOCKET (fdInf); - - /*if stack supply ep_create interface, just call create */ - nstack_each_modOps (modInx, ops) - { - - if (modInx == nstack_get_fix_mid ()) - { - nstack_set_protoFd (fdInf, modInx, epfd); - continue; - } - if (ops->pfepoll_create) - { - tfd = ops->pfepoll_create (size); - nstack_set_protoFd (fdInf, modInx, tfd); - } - } - - NSSOC_LOGINF ("fd=%d [return]", epfd); - set_fd_status_lock_fork (epfd, FD_OPEN); - UNLOCK_FOR_EP (lock_info); - return epfd; -} - -void -nstack_epoll_prewait_proc (int epfd, int *eventflag, int num) -{ - int modInx = 0; - nsep_epollInfo_t *epInfo = NULL; - epInfo = nsep_get_infoBySock (epfd); - if (!epInfo) - { - return; - } - nstack_each_modInx (modInx) - { - if (nstack_extern_deal (modInx).ep_prewait_proc) - { - if (epInfo->protoFD[modInx] < 0) - { - continue; - } - /*if already report event, maybe next time to do this proc */ - if ((eventflag) && (modInx < num) && (eventflag[modInx] != 0)) - { - continue; - } - nstack_extern_deal (modInx).ep_prewait_proc (epInfo->protoFD[modInx]); - } - } - return; -} + /* step1: get kernel epoll events and add them to epInfo */ +#ifdef KERNEL_FD_SUPPORT + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), epoll_wait, + (epfd, events, maxevents, 0), ret); + if (ret > 0) + { + /* here we should refill event.data from epi,which is revised by nstack_epoll_ctl */ + int i = 0; + nsep_epollInfo_t *fd_epinfo = NULL; + struct list_node *fd_epi_head = NULL; + struct list_node *node = NULL; + struct epitem *epi = NULL; + struct eventpoll *epfd_ep = NULL; -int -nstack_epoll_wait (int epfd, struct epoll_event *events, int maxevents, - int timeout) -{ - nstack_fd_Inf *fdInf = NULL; - nsep_epollInfo_t *epInfo = NULL; - struct eventpoll *ep = NULL; - int eventflag[NSEP_SMOD_MAX]; - int evt = 0; - int ret = 0; + for (i = 0; i < ret; i++) + { + fd_epinfo = nsep_get_info_by_sock(events[i].data.fd); + if (!fd_epinfo) + { + NSSOC_LOGERR("get null epInfo err]protoFD=%d", + events[i].data.fd); + continue; + } - NSTACK_INIT_CHECK_RET (epoll_wait, epfd, events, maxevents, timeout); + dmm_spin_lock_with_pid((dmm_spinlock_t *) (&fd_epinfo->epiLock)); /*do not need return value */ + fd_epi_head = + (struct list_node *) SHMEM_ADDR_SHTOL(fd_epinfo-> + epiList.head); + node = (struct list_node *) SHMEM_ADDR_SHTOL(fd_epi_head->next); + while (node) + { - NSTACK_FD_LINUX_CHECK (epfd, epoll_wait, fdInf, - (epfd, events, maxevents, timeout)); + epi = + (struct epitem *) ep_list_entry(node, struct epitem, + fllink); + epfd_ep = (struct eventpoll *) SHMEM_ADDR_SHTOL(epi->ep); - nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; - LOCK_EPOLL (epfd, fdInf, local_lock); + if (epfd_ep->epfd == epfd) + { + NSSOC_LOGDBG("Kernel got one event]i=%d,fd=%d,events=%u", + evt, events[i].data.fd, events[i].events); + events[evt].events = events[i].events; + events[evt].data = epi->event.data; + evt++; + break; + } - if (!NSTACK_IS_FD_EPOLL_SOCKET (fdInf)) - { - NSSOC_LOGWAR ("epfd=%d is not a epoll fd, return -1", epfd); - errno = EINVAL; - UNLOCK_EPOLL (epfd, local_lock); - return -1; + node = (struct list_node *) SHMEM_ADDR_SHTOL(node->next); + } + if (!node) + { + NSSOC_LOGINF("fd was not added to this epfd]fd=%d, epfd=%d", + events[i].data.fd, epfd); + } + dmm_spin_unlock((dmm_spinlock_t *) (&fd_epinfo->epiLock)); + } + /* end refill event.data */ } +#endif + /* step2: get events from epInfo(nstack's events). + 1)If have events, just return. + 2)If no event,wait and record new events. */ - /* check input paramter's validity */ - if (NULL == events) + ep_conn = SHMEM_ADDR_SHTOL(epInfo->ep_conn); + evt_ns = nsep_ep_poll(ep, &events[evt], (maxevents - evt), ep_conn); + if (evt_ns > 0) { - NSSOC_LOGWAR ("events is NULL, return -1 "); - errno = EINVAL; - UNLOCK_EPOLL (epfd, local_lock); - return -1; + evt += evt_ns; } - - epInfo = nsep_get_infoBySock (epfd); - if (NULL == epInfo) + if (evt) { - NSSOC_LOGWAR ("epInfo is NULL]epinfo=%p,epfd=%d", epInfo, epfd); - errno = EINVAL; - UNLOCK_EPOLL (epfd, local_lock); - return -1; + NSSOC_LOGDBG("Got event]epfd=%d,maxevents=%d,ret=%d", epfd, + maxevents, evt); + goto out; } - ep = ADDR_SHTOL (epInfo->ep); - if (NULL == ep) - { - NSSOC_LOGWAR ("fdInf->ep is NULL, return -1,epinfo=%p,epfd=%d", epInfo, - epfd); - errno = EINVAL; - UNLOCK_EPOLL (epfd, local_lock); - return -1; - } +#ifdef KERNEL_FD_SUPPORT + /* step3: if no event, add epfd to g_ksInfo.epfd epoll list and ks_ep_thread will record the new kernel epoll events to epinf */ + struct epoll_event ep_event; + ep_event.data.fd = epfd; + + ep_event.events = EPOLLIN | EPOLLET; - if (maxevents <= 0) + /* Here we don't check return value, because epfd maybe already in ks_ep_thread */ + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), epoll_ctl, + (0, EPOLL_CTL_ADD, epfd, &ep_event), ret); +#endif + + do { - NSSOC_LOGWAR ("maxevent less than zero maxevents=%d, return -1 ", - maxevents); - errno = EINVAL; - UNLOCK_EPOLL (epfd, local_lock); - return -1; + /*ns_sync_sem_timedwait need to deal timeout == 0 timeout < 0 timeout > 0 */ + ret = + g_ns_sync_ops.ns_sync_sem_timedwait(&ep->waitSem, timeout, + epInfo->sleepTime); + if (ret) + { + nsep_notify_fd_epoll_wait_fail(ep); + break; + } + evt = nsep_ep_poll(ep, events, maxevents, ep_conn); + if (evt) + { + NSSOC_LOGDBG("Got event]epfd=%d,maxevents=%d,ret=%d", epfd, + maxevents, evt); + break; + } } + while (1); + + /* step5: del epfd from g_ksInfo.epfd epoll list to make sure epoll_wait duration is the same as app */ +#ifdef KERNEL_FD_SUPPORT + + NSTACK_CAL_FUN(nstack_module_ops(nstack_get_linux_mid()), epoll_ctl, + (0, EPOLL_CTL_DEL, epfd, &ep_event), ret); +#endif + + out: + UNLOCK_EPOLL(epfd, local_lock); + ep->epoll_wait_pending = 0; + return evt; +} + +pid_t nstack_fork(void) +{ + pid_t pid; + pid_t ppid = sys_get_hostpid_from_file(getpid()); - /** - * For linux epoll - * Case 1: event is already there, means ks_ep_thread already reported, and epfd not in epoll. - * Case 2: event is not there, so we need to add epfd to ks_ep_thread - * Update : only try to add epfd to ks_ep_thread once, avoid ks_ep_thread reporting the same event again after app has got the event! - */ - MEMSET_S (&eventflag[0], sizeof (eventflag), 0, sizeof (eventflag)); - evt = nsep_ep_poll (ep, events, maxevents, &eventflag[0], NSEP_SMOD_MAX); - if (evt) + NSTACK_INIT_CHECK_RET(fork); + + if (ppid >= NSFW_MAX_PID || ppid <= 0) { - NSSOC_LOGDBG ("Got event]epfd=%d,maxevents=%d,ret=%d", epfd, maxevents, - evt); - nstack_epoll_prewait_proc (epfd, &eventflag[0], NSEP_SMOD_MAX); - goto out; + NSSOC_LOGERR("ppid over MAX_PID or not over 0]ppid=%d", ppid); + return -1; } - nstack_epoll_prewait_proc (epfd, NULL, 0); - do + dmm_write_lock(get_fork_lock()); + if (NSTACK_MODULE_SUCCESS == g_nStackInfo.fwInited) { - if (0 == timeout) - { - goto out; - } - else if (timeout < 0) + fork_parent_start(ppid); + pid = nsfw_base_fork(); + if (pid == 0) { - ret = sem_wait (&ep->waitSem); - /* when sem_wait return -1, epoll_wait should also return sem_wait's return value and errno */ - if (ret < 0) - { - /* Change sem_wait EINTR log to WAR level */ - if (errno == EINTR) - { - NSSOC_LOGWAR ("sem_wait return -1]errno=%d", errno); - } - else - { - NSSOC_LOGERR ("sem_wait return -1]errno=%d", errno); - } + fork_child_start(ppid); - evt = ret; - goto out; - } + /* when fork, the child process need + relese the lock in glog */ + nstack_log_lock_release(); + nstack_fork_init_child(ppid); + (void) nstack_for_epoll_init(); + nstack_fork_fd(ppid); + nsep_fork(ppid); + fork_child_done(ppid); } - else + else if (pid > 0) { - ret = - nstack_epoll_sem_timedwait (&ep->waitSem, (u64_t) timeout, - epInfo->sleepTime); + fork_wait_child_done(ppid); } - - if (ret) + else { - goto out; + fork_parent_failed(ppid); } - - evt = nsep_ep_poll (ep, events, maxevents, NULL, 0); - if (evt) + } + else + { + pid = nsfw_base_fork(); + if (pid == 0) { - NSSOC_LOGDBG ("Got event]epfd=%d,maxevents=%d,ret=%d", epfd, - maxevents, evt); - goto out; + updata_sys_pid(); } + NSSOC_LOGERR("g_nStackInfo has not initialized]ppid=%d, pid=%d", + ppid, pid); } - while (1); -out: - UNLOCK_EPOLL (epfd, local_lock); - return evt; + dmm_write_unlock(get_fork_lock()); + return pid; } -pid_t -nstack_fork (void) +int nstack_custom_peak(int fd) { - pid_t pid; - pid_t parent_pid = sys_get_hostpid_from_file (getpid ()); - - NSTACK_INIT_CHECK_RET (fork); + nstack_fd_Inf *fdInf = NULL; + int ret = 0; + int modInx = 0; - common_mem_rwlock_write_lock (get_fork_lock ()); - if (NSTACK_MODULE_SUCCESS == g_nStackInfo.fwInited) + fdInf = nstack_get_valid_inf(fd); + if (NULL == fdInf) { - nstack_fork_init_parent (parent_pid); - dmm_spinlock_lock_with_pid (nstack_get_fork_share_lock (), parent_pid); - pid = nsfw_base_fork (); - if (pid == 0) - { - /* when fork, the child process need relese the lock in glog */ - nstack_log_lock_release (); - nstack_fork_init_child (parent_pid); - (void) nstack_for_epoll_init (); - dmm_spinlock_lock_with_pid (nstack_get_fork_share_lock (), - get_sys_pid ()); - nsep_fork_child_proc (parent_pid); + nstack_set_errno(EINVAL); + NSSOC_LOGERR("invalid fd]fd=%d", fd); + return -1; + } - (void) select_module_init_child (); - common_mem_spinlock_unlock (nstack_get_fork_share_lock ()); - } - else if (pid > 0) - { - pid_t child_pid = get_hostpid_from_file (pid); - nsep_fork_parent_proc (parent_pid, child_pid); - common_mem_spinlock_unlock (nstack_get_fork_share_lock ()); - sys_sleep_ns (0, 10000000); /* wait child add pid for netconn */ - } - else - { - NSSOC_LOGERR ("fork failed]parent_pid=%d", parent_pid); - common_mem_spinlock_unlock (nstack_get_fork_share_lock ()); - } + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_RECV(fd, fdInf, local_lock); + + if (!NSTACK_IS_FD_ATTR(fdInf, fdInf->rd_item.type_data.attr)) + { + nstack_set_errno(EBADFD); + NSSOC_LOGERR("fd is not custom socket]fd=%d", fd); + UNLOCK_RECV(fd, fdInf, local_lock); + return -1; } - else + + nstack_fd_dfx_update_dfx_data(fd, fdInf->rlfd, fdInf->rmidx, + DMM_STAT_LONGEST_RECV_INTERVAL, NULL); + nstack_each_mod_inx(modInx) { - pid = nsfw_base_fork (); - if (pid == 0) + if (nstack_fd_deal[modInx].peak) { - update_sys_pid (); + ret = nstack_fd_deal[modInx].peak(fdInf->rlfd); } - NSSOC_LOGERR ("g_nStackInfo has not initialized]parent_pid=%d, pid=%d", - parent_pid, pid); + NSSOC_LOGDBG("Peak packet size]fd=%d,ret=%d", fd, ret); } + UNLOCK_RECV(fd, fdInf, local_lock); - common_mem_rwlock_write_unlock (get_fork_lock ()); - return pid; + return ret; } diff --git a/src/nSocket/nstack/nstack_socket.h b/src/nSocket/nstack/nstack_socket.h index 3bb7843..f63fb6c 100644 --- a/src/nSocket/nstack/nstack_socket.h +++ b/src/nSocket/nstack/nstack_socket.h @@ -19,94 +19,73 @@ #include <sys/socket.h> #include <poll.h> #include <sys/epoll.h> +#include <netdb.h> +#include "dmm_spinlock.h" +#include "nstack_fd_mng.h" #undef NSTACK_MK_DECL #define NSTACK_MK_DECL(ret, fn, args) extern ret nstack_##fn args -#include "declare_syscalls.h" +#include "declare_syscalls.h.tmpl" -int release_fd (int fd, nstack_fd_local_lock_info_t * local_lock); -int nstack_posix_api_init (); -int nstack_close (int fd); -int nstack_socket (int domain, int itype, int protocol); +int release_fd(int fd, nstack_fd_local_lock_info_t * local_lock); +int nstack_posix_api_init(); +int nstack_close(int fd); +int nstack_socket(int domain, int itype, int protocol); #define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, unlock) \ if ((NULL == inf) || ((inf)->attr & NSTACK_FD_ATTR_EPOLL_SOCKET)) \ { \ nstack_set_errno(err); \ NSSOC_LOGERR("nstack [%s] call, fd=0x%x is epoll fd return fail errno=%d [return]", #fun, fdVal, err); \ - unlock(fdVal, local_lock);\ + unlock(fdVal, inf, local_lock);\ return -1;\ } #define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON(fdVal, fun, inf, err, local_lock) \ - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_COMMON) - -#define LOCK_RECV(fd, fd_inf, local_lock)\ - LOCK_BASE_WITHOUT_KERNEL(fd, fd_inf, local_lock) - -#define UNLOCK_RECV(fd, local_lock) \ - UNLOCK_BASE(fd, local_lock) - -#define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fdVal, fun, inf, err, local_lock) \ - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_RECV) - -#define LOCK_SEND(fd, fd_inf, local_lock) \ - INC_FD_REF(fd, fd_inf, local_lock) - -static inline void -UNLOCK_SEND (int fd, nstack_fd_local_lock_info_t * local_lock) -{ - if ((NULL != local_lock) && atomic_dec (&local_lock->fd_ref) == 0) - { - release_fd (fd, local_lock); - } -} - -#define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fdVal, fun, inf, err, local_lock) \ - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_SEND) + /*do not need return value*/NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_COMMON) #define LOCK_CONNECT(fd, fd_inf, local_lock) \ - LOCK_BASE(fd, fd_inf, local_lock) + LOCK_BASE(fd, fd_inf, local_lock) -#define UNLOCK_CONNECT(fd, local_lock) \ - UNLOCK_BASE(fd, local_lock) +#define UNLOCK_CONNECT(fd, fd_inf, local_lock) \ + /*do not need return value*/UNLOCK_BASE(fd, fd_inf, local_lock) #define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_CONNECT(fdVal, fun, inf, err, local_lock) \ NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_CONNECT) #define LOCK_ACCEPT(fd, fd_inf, local_lock) \ - LOCK_BASE(fd, fd_inf, local_lock) + LOCK_BASE(fd, fd_inf, local_lock) -#define UNLOCK_ACCEPT(fd, local_lock) \ - UNLOCK_BASE(fd, local_lock) +#define UNLOCK_ACCEPT(fd, fd_inf, local_lock) \ + /*do not need return value*/UNLOCK_BASE(fd, fd_inf, local_lock) #define NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_ACCEPT(fdVal, fun, inf, err, local_lock) \ - NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_ACCEPT) + /*do not need return value*/NSTACK_EPOLL_FD_CHECK_RET_UNLOCK(fdVal, fun, inf, err, local_lock, UNLOCK_ACCEPT) -#define LOCK_EPOLL(fd, fd_inf, local_lock) INC_FD_REF(fd, fd_inf, local_lock) +#define LOCK_EPOLL(fd, fd_inf, local_lock) INC_FD_REF_RETURN(fd, fd_inf, local_lock) -static inline void -UNLOCK_EPOLL (int fd, nstack_fd_local_lock_info_t * local_lock) +static inline void UNLOCK_EPOLL(int fd, + nstack_fd_local_lock_info_t * local_lock) { - if ((NULL != local_lock) && atomic_dec (&local_lock->fd_ref) == 0) + if ((NULL != local_lock) && atomic_dec(&local_lock->fd_ref) == 0) { - release_fd (fd, local_lock); + release_fd(fd, local_lock); } } -#define LOCK_EPOLL_CTRL(fd_val, local_lock, epoll_fd, epoll_local_lock){\ +#define LOCK_EPOLL_CTRL_RETURN(fd_val, local_lock, epoll_fd, epoll_local_lock){\ if (local_lock)\ {\ atomic_inc(&local_lock->fd_ref);\ - common_mem_spinlock_lock(&local_lock->close_lock);\ - nstack_fd_Inf* fd_inf = nstack_getValidInf(fd_val);\ + dmm_spin_lock(&local_lock->close_lock);\ + nstack_fd_Inf* fd_inf = nstack_get_valid_inf(fd_val);\ if (fd_inf)\ {\ if (local_lock->fd_status != FD_OPEN)\ {\ NSSOC_LOGWAR("fd %d is not open [return]", fd_val);\ nstack_set_errno(EBADF);\ - common_mem_spinlock_unlock(&local_lock->close_lock);\ + dmm_spin_unlock(&local_lock->close_lock);\ if(atomic_dec(&local_lock->fd_ref)==0){ \ release_fd(fd_val, local_lock);\ }\ @@ -117,29 +96,29 @@ UNLOCK_EPOLL (int fd, nstack_fd_local_lock_info_t * local_lock) }\ } -static inline void -UNLOCK_EPOLL_CTRL (int fd, nstack_fd_local_lock_info_t * local_lock) +static inline void UNLOCK_EPOLL_CTRL(int fd, + nstack_fd_local_lock_info_t * local_lock) { - if (local_lock) + if (local_lock) { - common_mem_spinlock_unlock (&local_lock->close_lock); - if (atomic_dec (&local_lock->fd_ref) == 0) + dmm_spin_unlock(&local_lock->close_lock); + if (atomic_dec(&local_lock->fd_ref) == 0) { - release_fd (fd, local_lock); + release_fd(fd, local_lock); } } } -#define INC_FD_REF(fd, fd_inf, local_lock){ \ +#define INC_FD_REF_RETURN(fd, fd_inf, local_lock){ \ if (local_lock)\ {\ atomic_inc(&local_lock->fd_ref);\ if (local_lock->fd_status != FD_OPEN)\ {\ nstack_set_errno(EBADF);\ - NSSOC_LOGERR("nstack call, fd_status=%d [return]", local_lock->fd_status); \ + NSSOC_LOGERR("nstack call, nfd = %d, fd_status=%d [return]",fd, local_lock->fd_status); \ if(atomic_dec(&local_lock->fd_ref) == 0){ \ - release_fd(fd, local_lock);\ + release_fd(fd, local_lock);\ }\ return -1;\ }\ @@ -147,42 +126,41 @@ UNLOCK_EPOLL_CTRL (int fd, nstack_fd_local_lock_info_t * local_lock) } #define LOCK_BASE(fd, fd_inf, local_lock){\ - INC_FD_REF(fd, fd_inf, local_lock);\ + INC_FD_REF_RETURN(fd, fd_inf, local_lock);\ } /* if is kernel fd, don't need to lock */ #define LOCK_BASE_WITHOUT_KERNEL(fd, fd_inf, local_lock){\ - INC_FD_REF(fd, fd_inf, local_lock);\ + INC_FD_REF_RETURN(fd, fd_inf, local_lock);\ } -static inline void -UNLOCK_BASE (int fd, nstack_fd_local_lock_info_t * local_lock) +static inline void UNLOCK_BASE(int fd, nstack_fd_Inf * inf, + nstack_fd_local_lock_info_t * local_lock) { - if ((NULL != local_lock) && (atomic_dec (&local_lock->fd_ref) == 0)) + if ((NULL != local_lock) && (atomic_dec(&local_lock->fd_ref) == 0)) { - release_fd (fd, local_lock); + release_fd(fd, local_lock); } } #define LOCK_COMMON(fd, fd_inf, local_lock) \ LOCK_BASE(fd, fd_inf, local_lock) -#define UNLOCK_COMMON(fd, local_lock) \ - UNLOCK_BASE(fd, local_lock) +#define UNLOCK_COMMON(fd, fd_inf, local_lock) \ + /*do not need return value*/UNLOCK_BASE(fd, fd_inf, local_lock) #define LOCK_CLOSE(local_lock){\ if (local_lock)\ {\ - common_mem_spinlock_lock(&local_lock->close_lock);\ + dmm_spin_lock(&local_lock->close_lock);\ }\ } -static inline void -UNLOCK_CLOSE (nstack_fd_local_lock_info_t * local_lock) +static inline void UNLOCK_CLOSE(nstack_fd_local_lock_info_t * local_lock) { - if (local_lock) + if (local_lock) { - common_mem_spinlock_unlock (&local_lock->close_lock); + dmm_spin_unlock(&local_lock->close_lock); } } @@ -197,7 +175,7 @@ UNLOCK_CLOSE (nstack_fd_local_lock_info_t * local_lock) return nsfw_base_##fun(args); \ } \ if (nstack_fw_init()) { \ - NSSOC_LOGERR("nstack %s call, but initial not finished yet [return]", #fun); \ + NSSOC_LOGERR("nstack %s call, but initial not finished yet, errno %d [return]", #fun,get_fw_init_err()); \ nstack_set_errno(ENOSYS); \ return -1; \ } \ @@ -205,4 +183,6 @@ UNLOCK_CLOSE (nstack_fd_local_lock_info_t * local_lock) #define NSTACK_MODULE_ERROR_SET(Index) +extern int nstack_create_kernel_socket(); + #endif /* __NSTACK_SOCKET_H__ */ diff --git a/src/nSocket/nstack_rd/nstack_rd.c b/src/nSocket/nstack_rd/nstack_rd.c index 650f165..0c7d127 100644 --- a/src/nSocket/nstack_rd/nstack_rd.c +++ b/src/nSocket/nstack_rd/nstack_rd.c @@ -15,58 +15,72 @@ */ #include <stdlib.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> #include "nstack_rd.h" -#include "nstack_rd_init.h" #include "nstack_rd_priv.h" #include "nstack_rd_ip.h" +#include "nstack_rd_ip6.h" +#include "nstack_rd_type.h" #include "nstack_rd_proto.h" #include "nstack_log.h" -#include "nstack_info_parse.h" #include "nstack_securec.h" +#include <arpa/inet.h> -typedef struct __rd_data_defaut_ip -{ - char ip[RD_IP_STR_MAX_LEN]; - char stackname[RD_PLANE_NAMELEN]; - int masklent; -} rd_data_defaut_ip; +extern rd_route_table *g_rd_table_handle[]; -typedef struct __rd_data_defaut_protocol -{ - unsigned int proto_type; - char stackname[RD_PLANE_NAMELEN]; -} rd_data_defaut_protocol; +rd_local_data *g_rd_local_data = NULL; rd_data_proc g_rd_cpy[RD_DATA_TYPE_MAX] = { - { - nstack_rd_ipdata_cpy, - nstack_rd_ip_item_insert, - nstack_rd_ip_item_age, - nstack_rd_ip_item_find, - nstack_rd_ip_spec, - nstack_rd_ip_default, - }, - { - nstack_rd_proto_cpy, - nstack_rd_proto_item_insert, - nstack_rd_proto_item_age, - nstack_rd_proto_item_find, - nstack_rd_proto_spec, - nstack_rd_proto_default, - }, + { + nstack_rd_ip_data_cpy, + nstack_rd_ip_item_insert, + nstack_rd_ip_item_age, + nstack_rd_ip_item_clean, + nstack_rd_ip_item_find, + nstack_rd_ip_spec, + }, + { + nstack_rd_ip6_data_cpy, + nstack_rd_ip6_item_insert, + nstack_rd_ip6_item_age, + nstack_rd_ip6_item_clean, + nstack_rd_ip6_item_find, + nstack_rd_ip6_spec, + }, + { + nstack_rd_type_data_cpy, + nstack_rd_type_item_insert, + nstack_rd_type_item_age, + nstack_rd_type_item_clean, + nstack_rd_type_item_find, + nstack_rd_type_spec, + }, + { + nstack_rd_proto_data_cpy, + nstack_rd_proto_item_insert, + nstack_rd_proto_item_age, + nstack_rd_proto_item_clean, + nstack_rd_proto_item_find, + nstack_rd_proto_spec, + } }; -rd_data_defaut_ip g_default_ip_config[] = { - {{"127.0.0.1"}, {RD_KERNEL}, 32}, - {{"0.0.0.0"}, {RD_KERNEL}, 32}, -}; +int nstack_choose_highest_prio() +{ + int i; + int ret = 0; + int highest = 0x7FFFFFFF; + nstack_rd_stack_info *stack_info = g_rd_local_data->pstack_info; -rd_data_defaut_protocol g_default_protcol[] = { - {0xf001, {RD_LWIP}}, -}; + for (i = 0; i < NSTACK_NUM; i++) + { + if (stack_info[i].priority < highest) + { + highest = stack_info[i].priority; + ret = i; + } + } + return ret; +} /***************************************************************************** * Prototype : nstack_rd_get_stackid @@ -78,256 +92,414 @@ rd_data_defaut_protocol g_default_protcol[] = { * Calls : * Called By : *****************************************************************************/ -int -nstack_rd_get_stackid (nstack_rd_key * pkey, int *stackid) +int nstack_rd_get_stackid(nstack_rd_key * pkey, rd_data_item * item) { - int type = 0; - int ret = NSTACK_RD_SUCCESS; - rd_data_item item; - if ((!pkey) || (!stackid) || (pkey->type >= RD_DATA_TYPE_MAX)) + int accumulate = 0; + int icnt = 0; + int type = 0; + int ret = NSTACK_RD_SUCCESS; + int rdtbl_ver = 0; + if ((!pkey) || (!item) || (pkey->type >= RD_DATA_TYPE_MAX)) { - NSSOC_LOGERR ("input get stackid fail]addr=%p,stackid=%p,addr->type=%d", - pkey, stackid, !pkey ? RD_DATA_TYPE_MAX : pkey->type); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("input get stackid fail]addr=%p,item=%p,addr->type=%d", + pkey, item, !pkey ? RD_DATA_TYPE_MAX : pkey->type); + return NSTACK_RD_FAIL; } - int retVal = MEMSET_S (&item, sizeof (item), 0, sizeof (item)); - if (EOK != retVal) + /*add return value check */ + int retVal = + memset_s(item, sizeof(rd_data_item), 0, sizeof(rd_data_item)); + if (EOK != retVal) { - NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + return NSTACK_RD_FAIL; } - type = pkey->type; + item->stack_id = -1; + type = pkey->type; - /*specfic key find, for ip example: stack-x was chose if the key is multicast ip */ - if (g_rd_cpy[type].rd_item_spec) + /*specfic key find, for ip example: stackpool was chose if the key is multicast ip */ + if (g_rd_cpy[type].rd_item_spec) { - ret = g_rd_cpy[type].rd_item_spec ((void *) pkey); - if (ret >= 0) + ret = g_rd_cpy[type].rd_item_spec((void *) pkey); + if (ret >= 0) { - *stackid = ret; - return NSTACK_RD_SUCCESS; + item->stack_id = ret; + return NSTACK_RD_SUCCESS; } } - /*search the list */ - ret = - g_rd_cpy[type].rd_item_find (NSTACK_RD_LIST (type), (void *) pkey, &item); - if (NSTACK_RD_SUCCESS == ret) + /*check ver */ + for (icnt = 0; icnt < NSTACK_NUM; icnt++) { - NSSOC_LOGDBG ("item type=%d stackid=%d was found", pkey->type, - item.stack_id); - *stackid = item.stack_id; - return NSTACK_RD_SUCCESS; + retVal = + g_rd_local_data->rdtbl_ver_get_fun(&rdtbl_ver, + g_rd_table_handle[icnt]); + if (retVal) + { + NSSOC_LOGWAR("stackid=%d get rd table ver failed!", + g_rd_local_data->pstack_info->stack_id); + if (++accumulate < NSTACK_NUM) + { + continue; + } + NSSOC_LOGERR("rd table ver get failed"); + return NSTACK_RD_FAIL; + } + if (g_rd_local_data->rdlocal_ver[icnt] != rdtbl_ver) + { + NSSOC_LOGINF + ("RD table ver unmatch]new rd tlbver:%d,local rd tblver:%d,resync now", + rdtbl_ver, g_rd_local_data->rdlocal_ver[icnt]); + ret = nstack_rd_sys(); + if (ret != NSTACK_RD_SUCCESS) + { + item->stack_id = nstack_choose_highest_prio(); + NSSOC_LOGERR + ("sync RD INF failed, choose highest priority stack, stackid=%d", + item->stack_id); + return NSTACK_RD_SUCCESS; + } + } } - if (g_rd_cpy[type].rd_item_default) + + /*search the list */ + ret = + g_rd_cpy[type].rd_item_find(NSTACK_RD_LIST(type), (void *) pkey, + item); + if (NSTACK_RD_SUCCESS == ret) { - *stackid = g_rd_cpy[type].rd_item_default ((void *) pkey); + NSSOC_LOGDBG("item type=%d stackid=%d was found", pkey->type, + item->stack_id); + return NSTACK_RD_SUCCESS; } - else + item->stack_id = nstack_choose_highest_prio(); + NSSOC_LOGINF + ("item type=%d was not found, choose highest priority stack by default, stackid=%d", + pkey->type, item->stack_id); + return NSTACK_RD_SUCCESS; +} + +static char *nstack_rd_parse_ip(char *pos, unsigned int *ip) +{ + char buf[16]; + char *p; + int len, ret; + + if (!pos) + return NULL; + + p = strchr(pos, '/'); + if (!p) + return NULL; + + len = p - pos; + if (len >= 16) + return NULL; + + ret = memcpy_s(buf, sizeof(buf), pos, len); + if (EOK != ret) { - *stackid = -1; + return NULL; } - NSSOC_LOGINF ("item type=%d was not found, return default=%d", pkey->type, - *stackid); - return NSTACK_RD_SUCCESS; + + buf[len] = 0; + + ret = inet_pton(AF_INET, buf, ip); + if (ret == 1) + return p + 1; + + return NULL; + } -/***************************************************************************** -* Prototype : nstack_rd_sys_default -* Description : sys default rd info, -* Input : None -* Output : None -* Return Value : int -* Calls : -* Called By : -******************************************************************************/ -void -nstack_rd_sys_default () +static char *nstack_rd_parse_ip6(char *pos, unsigned int ip[4]) +{ + char buf[46]; + char *p; + int len, ret; + + p = strchr(pos, '/'); + if (!p) + return NULL; + + len = p - pos; + if (len >= 46) + return NULL; + + (void) memcpy_s(buf, sizeof(buf), pos, len); + buf[len] = 0; + + ret = inet_pton(AF_INET6, buf, ip); + if (ret == 1) + return p + 1; + + return NULL; +} + +static char *nstack_rd_parse_stackid(char *pos, int *stack_id) { - rd_data_item item; - rd_data_defaut_ip *pdata = NULL; - rd_data_defaut_protocol *pprotodata = NULL; - int icnt = 0, iindex = 0; - int stack_num = 0; + size_t n = 0; + int i; - stack_num = g_rd_local_data->stack_num; + while (pos[n] != ':' && pos[n] != 0) + n++; + if (n == 0 || n >= RD_PLANE_NAMELEN) + return NULL; - /*get the ip default route */ - for (icnt = 0; - icnt < sizeof (g_default_ip_config) / sizeof (rd_data_defaut_ip); - icnt++) + for (i = 0; i < g_rd_local_data->stack_num; ++i) { - pdata = &g_default_ip_config[icnt]; - for (iindex = 0; iindex < stack_num; iindex++) + /* params are not NULL */ + if (0 == strncmp(pos, g_rd_local_data->pstack_info[i].name, n)) { - if (0 == - strcmp (g_rd_local_data->pstack_info[iindex].name, - pdata->stackname)) - { - item.stack_id = g_rd_local_data->pstack_info[iindex].stack_id; - break; - } + *stack_id = g_rd_local_data->pstack_info[i].stack_id; + return pos + n; } - if (iindex >= stack_num) + } + + return NULL; +} + +static void nstack_rd_sys_load_default() +{ + char *env, *pos; + + env = getenv("NSTACK_RD"); /*this func can be used */ + + if (!env || !env[0]) + return; + + pos = env; + while (*pos) + { + rd_data_item item; + char *pos6 = pos; + + pos = nstack_rd_parse_ip(pos, &item.ipdata.addr); + if (pos) { - NSSOC_LOGINF - ("default stack name:%s was not fount, ip:%s msklen:%d was dropped", - pdata->stackname, pdata->ip, pdata->masklent); - continue; + item.type = RD_DATA_TYPE_IP; + item.agetime = NSTACK_RD_AGETIME_MAX; + item.ipdata.resev[0] = 0; + item.ipdata.resev[1] = 0; + item.ipdata.masklen = (unsigned int) strtoul(pos, &pos, 10); + if (item.ipdata.masklen > 32 || *pos++ != '=') + { + NSSOC_LOGERR("nstack rd sys config error '%s'", env); + return; + } } - item.type = RD_DATA_TYPE_IP; - item.ipdata.addr = ntohl (inet_addr (pdata->ip)); - item.ipdata.masklen = pdata->masklent; - item.ipdata.resev[0] = 0; - item.ipdata.resev[1] = 0; - item.agetime = NSTACK_RD_AGETIME_MAX; - /*insert to the list */ - g_rd_cpy[RD_DATA_TYPE_IP].rd_item_inset (NSTACK_RD_LIST - (RD_DATA_TYPE_IP), &item); - } - - /*get the protocol default route */ - (void) MEMSET_S (&item, sizeof (item), 0, sizeof (item)); - for (icnt = 0; - icnt < sizeof (g_default_protcol) / sizeof (rd_data_defaut_protocol); - icnt++) - { - pprotodata = &g_default_protcol[icnt]; - for (iindex = 0; iindex < stack_num; iindex++) + else if (NULL != + (pos = nstack_rd_parse_ip6(pos6, item.ip6data.addr.addr32))) { - if (0 == - strcmp (g_rd_local_data->pstack_info[iindex].name, - pprotodata->stackname)) + item.type = RD_DATA_TYPE_IP6; + item.agetime = NSTACK_RD_AGETIME_MAX; + item.ip6data.masklen = (unsigned int) strtoul(pos, &pos, 10); + if (item.ip6data.masklen > 128 || *pos++ != '=') { - item.stack_id = g_rd_local_data->pstack_info[iindex].stack_id; - break; + NSSOC_LOGERR("nstack rd sys config error '%s'", env); + return; } } - if (iindex >= stack_num) + else { - NSSOC_LOGINF - ("default stack name:%s was not fount, protocoltype:%d was dropped", - pprotodata->stackname, pprotodata->proto_type); - continue; + NSSOC_LOGERR("nstack rd sys config error '%s'", env); + return; } - item.type = RD_DATA_TYPE_PROTO; - item.proto_type = pprotodata->proto_type; - /*insert to the list */ - g_rd_cpy[RD_DATA_TYPE_PROTO].rd_item_inset (NSTACK_RD_LIST - (RD_DATA_TYPE_PROTO), + + pos = nstack_rd_parse_stackid(pos, &item.stack_id); + if (!pos) + { + NSSOC_LOGERR("nstack rd sys config error '%s'", env); + return; + } + + (void) g_rd_cpy[item.type].rd_item_insert(NSTACK_RD_LIST(item.type), &item); - } - return; -} -/***************************************************************************** -* Prototype : nstack_rd_save -* Description : save the rd data -* Input : None -* Output : None -* Return Value : int -* Calls : -* Called By : -*****************************************************************************/ -void -nstack_rd_save (rd_route_data * rd_data, int num) -{ - int icnt = 0; - int iindex = 0; - int stack_num = 0; - rd_data_item item; - rd_data_type type = RD_DATA_TYPE_MAX; + if (item.type == RD_DATA_TYPE_IP6) + { + char buf[46]; + NSSOC_LOGINF("insert one RD %d=%s/%u", item.stack_id, + inet_ntop(AF_INET6, &item.ip6data.addr, buf, + sizeof(buf)), item.ip6data.masklen); + } + else + { + NSSOC_LOGINF("insert one RD %d:%u.%u.%u.%u/%u", item.stack_id, + item.ipdata.addr >> 24, + (item.ipdata.addr >> 16) & 255, + (item.ipdata.addr >> 8) & 255, + item.ipdata.addr & 255, item.ipdata.masklen); + } - int retVal = MEMSET_S (&item, sizeof (item), 0, sizeof (item)); - if (EOK != retVal) - { - NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); - return; + if (*pos == ':') + pos++; } +} - stack_num = g_rd_local_data->stack_num; - - for (iindex = 0; iindex < num; iindex++) +static void nstack_rd_sys_clean() +{ + int type; + for (type = 0; type < RD_DATA_TYPE_MAX; type++) { - if (rd_data[iindex].type >= RD_DATA_TYPE_MAX) + if (!hlist_empty(&(NSTACK_RD_LIST(type)->headlist))) { - NSSOC_LOGERR ("rd data type=%d unkown", rd_data[iindex].type); - continue; + g_rd_cpy[type].rd_item_clean(NSTACK_RD_LIST(type)); } + } +} - type = rd_data[iindex].type; +static int nstack_rd_ip_get(rd_route_data ** data, int *num, int *ver, + rd_route_table * handle) +{ + rd_route_data *pdata = NULL; + rd_route_node *pnode = NULL; + size_t size = 0; + int icnt = 0; + int idex = 0; + int ret; + int rdver = 0; - if (NSTACK_RD_SUCCESS == - g_rd_cpy[type].rd_item_cpy ((void *) &item, - (void *) &rd_data[iindex])) + if (!handle || !data || !num || !ver) + { + NSSOC_LOGERR("nstack rd mng not inited or input err"); + return -1; + } + dmm_spin_lock_with_pid(&handle->rd_lock); + size = sizeof(rd_route_data) * handle->size; + pdata = (rd_route_data *) malloc(size); + if (!pdata) + { + dmm_spin_unlock(&handle->rd_lock); + NSSOC_LOGERR("rd route data malloc fail"); + return -1; + } + ret = memset_s(pdata, size, 0, size); + if (EOK != ret) + { + dmm_spin_unlock(&handle->rd_lock); + NSSOC_LOGERR("memset_s failed]ret=%d", ret); + free(pdata); + return -1; + } + for (icnt = 0; icnt < handle->size; icnt++) + { + pnode = &(handle->node[icnt]); + if (RD_NODE_USING == pnode->flag) { - item.agetime = NSTACK_RD_AGETIME_MAX; - for (icnt = 0; icnt < stack_num; icnt++) - { - if (0 == - strcmp (g_rd_local_data->pstack_info[icnt].name, - rd_data[iindex].stack_name)) - { - item.stack_id = g_rd_local_data->pstack_info[icnt].stack_id; - break; - } - } - if (icnt >= stack_num) - { - NSSOC_LOGINF - ("plane name:%s was not fount, protocoltype:%d was dropped", - rd_data[iindex].stack_name); - continue; - } - /*insert to the list */ - g_rd_cpy[type].rd_item_inset (NSTACK_RD_LIST (type), &item); - continue; + pdata[idex] = pnode->data; + idex++; } + } + rdver = handle->rdtbl_ver; + dmm_spin_unlock(&handle->rd_lock); + /*if no data fetched , just return fail */ + if (idex == 0) + { + free(pdata); + return -1; + } + *data = pdata; + *num = idex; + *ver = rdver; + return 0; +} - NSSOC_LOGERR ("rd data type=%d cpy fail", rd_data[iindex].type); +static int nstack_rd_tblver_get(int *ver, rd_route_table * handle) +{ + if (!handle || !ver) + { + NSSOC_LOGERR("nstack rd mng not inited or input err"); + return -1; } - return; + *ver = handle->rdtbl_ver; + return 0; } -/***************************************************************************** -* Prototype : nstack_rd_data_get -* Description : rd data get, -* Input : None -* Output : None -* Return Value : int -* Calls : -* Called By : -*****************************************************************************/ -int -nstack_rd_data_get (nstack_get_route_data pfun) +int nstack_rd_init(nstack_rd_stack_info * pstack, int num) { - rd_route_data *rd_data = NULL; - int iret = NSTACK_RD_FAIL; - int inum = 0; + int icnt = 0; + nstack_rd_stack_info *ptemstack = NULL; + int *rd_ver = NULL; - /*get rd config */ - if (pfun && (NSTACK_RD_SUCCESS == pfun (&rd_data, &inum))) + if (!pstack) { - if (inum > 0) - { - nstack_rd_save (rd_data, inum); - iret = NSTACK_RD_SUCCESS; - } - else - { - NSSOC_LOGDBG ("no rd data got"); - } - if (rd_data) - { - free (rd_data); - rd_data = NULL; - } + NSSOC_LOGERR("input err pstack:%p", pstack); + return NSTACK_RD_FAIL; + } + g_rd_local_data = (rd_local_data *) malloc(sizeof(rd_local_data)); + if (!g_rd_local_data) + { + NSSOC_LOGERR("g_rd_local_data alloc fail"); + return NSTACK_RD_FAIL; + } + + /*add return value check */ + if (EOK != + memset_s((void *) g_rd_local_data, sizeof(rd_local_data), 0, + sizeof(rd_local_data))) + { + NSSOC_LOGERR("memset_s fail"); + goto ERR; + } + + g_rd_local_data->sys_fun = nstack_rd_ip_get; + g_rd_local_data->rdtbl_ver_get_fun = nstack_rd_tblver_get; + + ptemstack = + (nstack_rd_stack_info *) malloc(sizeof(nstack_rd_stack_info) * num); + if (!ptemstack) + { + NSSOC_LOGERR("rd stack info malloc fail"); + goto ERR; + } + + if (EOK != + memcpy_s(ptemstack, sizeof(nstack_rd_stack_info) * num, pstack, + sizeof(nstack_rd_stack_info) * num)) + { + NSSOC_LOGERR("memcpy_s failed!"); + goto ERR; + } + + g_rd_local_data->pstack_info = ptemstack; + g_rd_local_data->stack_num = num; + + rd_ver = (int *) malloc(sizeof(int) * NSTACK_NUM); /*this function is necessary */ + if (!rd_ver) + { + NSSOC_LOGERR("rd_ver alloc failed!"); + goto ERR; + } + if (EOK != + memset_s((void *) rd_ver, sizeof(int) * NSTACK_NUM, 0, + sizeof(int) * NSTACK_NUM)) + { + NSSOC_LOGERR("memset_s failed!"); + goto ERR; + } + g_rd_local_data->rdlocal_ver = rd_ver; + + for (icnt = 0; icnt < RD_DATA_TYPE_MAX; icnt++) + { + INIT_HLIST_HEAD(&(g_rd_local_data->route_list[icnt].headlist)); } - else + return NSTACK_RD_SUCCESS; + + ERR: + if (g_rd_local_data) + { + free(g_rd_local_data); + g_rd_local_data = NULL; + } + if (ptemstack) { - NSSOC_LOGERR ("nstack rd sys rd info fail"); + free(ptemstack); } - return iret; + if (rd_ver) + { + free(rd_ver); /*this function is necessary */ + } + return NSTACK_RD_FAIL; } /***************************************************************************** @@ -339,33 +511,92 @@ nstack_rd_data_get (nstack_get_route_data pfun) * Calls : * Called By : *****************************************************************************/ -int -nstack_rd_sys () +int nstack_rd_sys() { - int iret = NSTACK_RD_FAIL; - int icnt = 0; - if (!g_rd_local_data) + rd_route_data *rd_data = NULL; + nstack_rd_stack_info *prdstack = NULL; + int icnt = 0; + int inum = 0; + int iver = 0; + int iret = 0; + int iindex = 0; + rd_data_item item; + rd_data_type type = RD_DATA_TYPE_MAX; + + if (!g_rd_local_data) { - NSSOC_LOGERR ("rd have not been inited"); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("rd have not been inited"); + return NSTACK_RD_FAIL; } + /*add return value check */ + int retVal = memset_s(&item, sizeof(item), 0, sizeof(item)); + if (EOK != retVal) + { + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + return NSTACK_RD_FAIL; + } + nstack_rd_sys_clean(); - /*insert default rd info */ - nstack_rd_sys_default (); + nstack_rd_sys_load_default(); - /*get from config file */ - for (icnt = 0; icnt < g_rd_local_data->fun_num; icnt++) + prdstack = g_rd_local_data->pstack_info; + for (icnt = 0; icnt < NSTACK_NUM; icnt++) { - if (NSTACK_RD_SUCCESS == - nstack_rd_data_get (g_rd_local_data->sys_fun[icnt])) + if (!g_rd_table_handle[icnt]) { - iret = NSTACK_RD_SUCCESS; + continue; } - } + /*get from rd table */ + iret = + g_rd_local_data->sys_fun(&rd_data, &inum, &iver, + g_rd_table_handle[icnt]); + if (NSTACK_RD_SUCCESS != iret) + { + NSSOC_LOGERR("nstack rd sys rd info stack fail] stack=%s", + prdstack[icnt].name); + return NSTACK_RD_FAIL; + } + NSSOC_LOGINF + ("nstack rd sync sucess] stack=%s, rdtable ver:%d, rdtable size:%d", + prdstack[icnt].name, iver, inum); - /*age after sys */ - nstack_rd_age (); - return iret; + g_rd_local_data->rdlocal_ver[icnt] = iver; + if (inum <= 0) + { + NSSOC_LOGDBG("no rd data got"); + if (rd_data) + { + free(rd_data); /*this function is necessary */ + rd_data = NULL; + } + continue; + } + for (iindex = 0; iindex < inum; iindex++) + { + if (rd_data[iindex].type >= RD_DATA_TYPE_MAX) + { + NSSOC_LOGERR("rd data type=%d unkown", rd_data[iindex].type); + continue; + } + type = rd_data[iindex].type; + if (NSTACK_RD_SUCCESS == + g_rd_cpy[type].rd_item_copy((void *) &item, + (void *) &rd_data[iindex])) + { + item.agetime = NSTACK_RD_AGETIME_MAX; + item.stack_id = prdstack[icnt].stack_id; + /*insert to the list */ + g_rd_cpy[type].rd_item_insert(NSTACK_RD_LIST(type), &item); /*do not need return value */ + continue; + } + NSSOC_LOGERR("rd data type=%d cpy fail", rd_data[iindex].type); + } + free(rd_data); /*this function is necessary */ + rd_data = NULL; + } + /*age after sys */ + nstack_rd_age(); /*do not need return value */ + return NSTACK_RD_SUCCESS; } /***************************************************************************** @@ -378,13 +609,42 @@ nstack_rd_sys () * Calls : * Called By : *****************************************************************************/ -int -nstack_rd_age () +int nstack_rd_age() { - int icnt = 0; - for (icnt = 0; icnt < RD_DATA_TYPE_MAX; icnt++) + int icnt = 0; + for (icnt = 0; icnt < RD_DATA_TYPE_MAX; icnt++) { - (void) g_rd_cpy[icnt].rd_item_age (NSTACK_RD_LIST (icnt)); + if (g_rd_cpy[icnt].rd_item_age) + (void) g_rd_cpy[icnt].rd_item_age(NSTACK_RD_LIST(icnt)); } - return NSTACK_RD_SUCCESS; + return NSTACK_RD_SUCCESS; +} + +int nstack_rd_match_pre(int domain, int type, int protocol, + rd_data_item * item) +{ + int ret = -1; + nstack_rd_key key = { 0 }; + + key.type = RD_DATA_TYPE_TYPE; + key.socket_type = type; + ret = + g_rd_cpy[key.type].rd_item_find(NSTACK_RD_LIST(key.type), + (void *) &key, (void *) item); + if (ret == NSTACK_RD_SUCCESS) + { + return item->stack_id; + } + + key.type = RD_DATA_TYPE_PROTO; + key.proto = protocol; + ret = + g_rd_cpy[key.type].rd_item_find(NSTACK_RD_LIST(key.type), + (void *) &key, (void *) item); + if (ret == NSTACK_RD_SUCCESS) + { + return item->stack_id; + } + + return -1; } diff --git a/src/nSocket/nstack_rd/nstack_rd_init.c b/src/nSocket/nstack_rd/nstack_rd_init.c deleted file mode 100644 index 09186ae..0000000 --- a/src/nSocket/nstack_rd/nstack_rd_init.c +++ /dev/null @@ -1,171 +0,0 @@ -/* -* -* Copyright (c) 2018 Huawei Technologies Co.,Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at: -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include <stdlib.h> -#include "nstack_rd.h" -#include "nstack_rd_data.h" -#include "nstack_rd_init.h" -#include "nstack_rd_priv.h" -#include "nstack_log.h" -#include "nstack_securec.h" - -#define NSTACK_RD_ERR_CHECK_GOTO(ret, desc, lab) \ -if (NSTACK_RD_SUCCESS != (ret))\ -{ \ - NSSOC_LOGERR("%s fail, return:%d", desc, ret); \ - goto lab; \ -} - -#define NSTACK_RD_POINT_CHECK_GOTO(ptr, desc, lab) \ -if (!ptr)\ -{ \ - NSSOC_LOGERR("%s fail", desc); \ - goto lab; \ -} - -rd_local_data *g_rd_local_data = NULL; - -/***************************************************************************** -* Prototype : nstack_rd_init -* Description : nstack rd init -* Input : nstack_stack_info *pstack -* int num -* nstack_get_route_data pfun -* Output : None -* Return Value : int -* Calls : -* Called By : -* pstack : 1. priority 0: when router not fund, the first will be chose -* 2. if have many same 0 priority, fist input will be chose, -* 3. if none 0 priority, the last input will be choose -*****************************************************************************/ -int -nstack_rd_init (nstack_stack_info * pstack, int num, - nstack_get_route_data * pfun, int fun_num) -{ - int icnt = 0; - int hindex = 0; - int tindex = num - 1; - int iindex = 0; - int ret = NSTACK_RD_SUCCESS; - nstack_rd_stack_info *ptemstack = NULL; - - if ((!pstack) || (!pfun)) - { - NSSOC_LOGERR ("input err pstack:%p, pfun:%p", pstack, pfun); - return NSTACK_RD_FAIL; - } - g_rd_local_data = (rd_local_data *) malloc (sizeof (rd_local_data)); - if (!g_rd_local_data) - { - NSSOC_LOGERR ("g_rd_local_data alloc fail"); - return NSTACK_RD_FAIL; - } - - if (EOK != - MEMSET_S ((void *) g_rd_local_data, sizeof (rd_local_data), 0, - sizeof (rd_local_data))) - { - NSSOC_LOGERR ("MEMSET_S fail"); - goto ERR; - } - for (icnt = 0; icnt < fun_num; icnt++) - { - g_rd_local_data->sys_fun[icnt] = pfun[icnt]; - } - g_rd_local_data->fun_num = fun_num; - ptemstack = - (nstack_rd_stack_info *) malloc (sizeof (nstack_rd_stack_info) * num); - NSTACK_RD_POINT_CHECK_GOTO (ptemstack, "rd stack info malloc fail", ERR); - - /*save stack info in priority order */ - for (icnt = 0; icnt < num; icnt++) - { - if (0 == pstack[icnt].priority) - { - iindex = hindex; - hindex++; - } - else - { - iindex = tindex; - tindex--; - } - - /* modify destMax from RD_PLANE_NAMELEN to STACK_NAME_MAX */ - ret = - STRCPY_S (ptemstack[iindex].name, STACK_NAME_MAX, pstack[icnt].name); - if (ret != EOK) - { - NSSOC_LOGERR ("STRCPY_S failed"); - goto ERR; - } - - ptemstack[iindex].priority = pstack[icnt].priority; - ptemstack[iindex].stack_id = pstack[icnt].stack_id; - NSSOC_LOGDBG - ("nstack rd init]stackname=%s,priority=%d,stackid=%d was added", - ptemstack[iindex].name, - ptemstack[iindex].priority, ptemstack[iindex].stack_id); - } - - g_rd_local_data->pstack_info = ptemstack; - g_rd_local_data->stack_num = num; - - for (icnt = 0; icnt < RD_DATA_TYPE_MAX; icnt++) - { - INIT_HLIST_HEAD (&(g_rd_local_data->route_list[icnt].headlist)); - } - return NSTACK_RD_SUCCESS; - -ERR: - if (g_rd_local_data) - { - free (g_rd_local_data); - g_rd_local_data = NULL; - } - if (ptemstack) - { - free (ptemstack); - } - return NSTACK_RD_FAIL; -} - -/***************************************************************************** -* Prototype : nstack_get_stackid_byname -* Description : get stack ip by stack name -* Input : char *name -* Output : None -* Return Value : int -* Calls : -* Called By : -*****************************************************************************/ -int -nstack_get_stackid_byname (char *name) -{ - int stacknum = g_rd_local_data->stack_num; - int iindex = 0; - nstack_rd_stack_info *pstack = NULL; - for (iindex = 0; iindex < stacknum; iindex++) - { - pstack = &(g_rd_local_data->pstack_info[iindex]); - if (0 == strcmp (pstack->name, name)) - { - return pstack->stack_id; - } - } - return -1; -} diff --git a/src/nSocket/nstack_rd/nstack_rd_ip.c b/src/nSocket/nstack_rd/nstack_rd_ip.c index 82035d1..d769720 100644 --- a/src/nSocket/nstack_rd/nstack_rd_ip.c +++ b/src/nSocket/nstack_rd/nstack_rd_ip.c @@ -18,157 +18,158 @@ #include <arpa/inet.h> #include "nstack_rd_data.h" #include "nstack_rd.h" -#include "nstack_rd_init.h" #include "nstack_rd_priv.h" #include "nstack_rd_ip.h" #include "nstack_log.h" #include "nstack_securec.h" +/* Optimize log */ #include "nstack_ip_addr.h" -#define NSTACK_IP_MLSTACKID RD_LWIP - #define PP_HTONL(x) ((((x) & 0xff) << 24) | \ (((x) & 0xff00) << 8) | \ (((x) & 0xff0000UL) >> 8) | \ (((x) & 0xff000000UL) >> 24)) -#define rd_ismulticast(addr)(((unsigned int)(addr) & 0xf0000000UL) == 0xe0000000UL) +#define rd_ismulticast(addr)(((ntohl(addr)) & 0xf0000000UL) == 0xe0000000UL) int g_multi_stackid = -1; /*copy rd data*/ -int -nstack_rd_ipdata_cpy (void *destdata, void *srcdata) +int nstack_rd_ip_data_cpy(void *destdata, void *srcdata) { - rd_data_item *pitem = (rd_data_item *) destdata; - rd_route_data *pdata = (rd_route_data *) srcdata; - - pitem->type = pdata->type; - pitem->ipdata.addr = pdata->ipdata.addr; - pitem->ipdata.masklen = pdata->ipdata.masklen; - pitem->ipdata.resev[0] = pdata->ipdata.resev[0]; - pitem->ipdata.resev[1] = pdata->ipdata.resev[1]; - return NSTACK_RD_SUCCESS; + rd_data_item *pitem = (rd_data_item *) destdata; + rd_route_data *pdata = (rd_route_data *) srcdata; + + pitem->type = pdata->type; + pitem->ipdata.addr = pdata->ipdata.addr; + pitem->ipdata.masklen = pdata->ipdata.masklen; + pitem->ipdata.resev[0] = pdata->ipdata.resev[0]; + pitem->ipdata.resev[1] = pdata->ipdata.resev[1]; + return NSTACK_RD_SUCCESS; } /* * Add an ip segment to the list and sort it in descending order of ip mask length * If the list already exists in the same list of ip side, then stack_id update - *ip is local byteorder + *ip is network byte order */ -int -nstack_rd_ip_item_insert (nstack_rd_list * hlist, void *rditem) +/*vars are used in macro*/ +int nstack_rd_ip_item_insert(nstack_rd_list * hlist, void *rditem) { - nstack_rd_node *pdatanode = NULL; - nstack_rd_node *tempdata = NULL; - struct hlist_node *tempnode = NULL; - struct hlist_node *tem = NULL; - - unsigned int tempip_addr = 0; - unsigned int tempip_masklen = 0; - rd_data_item *pitem = (rd_data_item *) rditem; - unsigned int ip_addr = pitem->ipdata.addr; - unsigned int ip_masklen = pitem->ipdata.masklen; - unsigned int ip_maskv = MASK_V (ip_addr, ip_masklen); - - ip_masklen = pitem->ipdata.masklen; - NSSOC_LOGDBG ("stackid:%d, ipaddr:%u.%u.%u.%u masklen:0x%x was inserted", - pitem->stack_id, ip4_addr4_16 (&pitem->ipdata.addr), - ip4_addr3_16 (&pitem->ipdata.addr), - ip4_addr2_16 (&pitem->ipdata.addr), - ip4_addr1_16 (&pitem->ipdata.addr), pitem->ipdata.masklen); - - pdatanode = (nstack_rd_node *) malloc (sizeof (nstack_rd_node)); - if (!pdatanode) + nstack_rd_node *pdatanode = NULL; + nstack_rd_node *tempdata = NULL; + struct hlist_node *tempnode = NULL; + struct hlist_node *tem = NULL; + unsigned int ip_addr = 0; + unsigned int ip_masklen = 0; + unsigned int ip_maskv = 0; + unsigned int tempip_addr = 0; + unsigned int tempip_masklen = 0; + rd_data_item *pitem = (rd_data_item *) rditem; + + ip_masklen = pitem->ipdata.masklen; + ip_addr = pitem->ipdata.addr; + ip_maskv = MASK_V(ip_addr, ip_masklen); + + /* Optimize log */ + NSSOC_LOGDBG("stackid:%d, ipaddr:*.*.%u.%u masklen:0x%x was inserted", + pitem->stack_id, FUZZY_IP_VAR(&pitem->ipdata.addr), + pitem->ipdata.masklen); + + pdatanode = (nstack_rd_node *) malloc(sizeof(nstack_rd_node)); /*this function is necessary */ + if (!pdatanode) { - NSSOC_LOGERR ("nstack rd item malloc fail"); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("nstack rd item malloc fail"); + return NSTACK_RD_FAIL; } - int retVal = - MEMSET_S (pdatanode, sizeof (nstack_rd_node), 0, sizeof (nstack_rd_node)); - if (EOK != retVal) + /* add return value check */ + int retVal = memset_s(pdatanode, sizeof(nstack_rd_node), 0, + sizeof(nstack_rd_node)); + if (EOK != retVal) { - NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); - free (pdatanode); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_FAIL; } - INIT_HLIST_NODE (&pdatanode->rdnode); - NSTACK_RD_IP_ITEM_COPY (&(pdatanode->item), pitem); + INIT_HLIST_NODE(&pdatanode->rdnode); + NSTACK_RD_IP_ITEM_COPY(&(pdatanode->item), pitem); - if (hlist_empty (&(hlist->headlist))) + if (hlist_empty(&(hlist->headlist))) { - hlist_add_head (&(pdatanode->rdnode), &(hlist->headlist)); - return NSTACK_RD_SUCCESS; + hlist_add_head(&(pdatanode->rdnode), &(hlist->headlist)); + + return NSTACK_RD_SUCCESS; + } - hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) - { - tem = tempnode; - tempip_addr = tempdata->item.ipdata.addr; - tempip_masklen = tempdata->item.ipdata.masklen; - if (ip_masklen < tempip_masklen) - { - continue; - } - - /*if already exist, just return success */ - if (ip_maskv == MASK_V (tempip_addr, tempip_masklen)) - { - NSSOC_LOGDBG - ("insert ip:%u.%u.%u.%u, mask:0x%x, stack_id:%d, exist orgid:%d", - ip4_addr4_16 (&pitem->ipdata.addr), - ip4_addr3_16 (&pitem->ipdata.addr), - ip4_addr2_16 (&pitem->ipdata.addr), - ip4_addr1_16 (&pitem->ipdata.addr), pitem->ipdata.masklen, - pitem->stack_id, tempdata->item.stack_id); - - tempdata->item.stack_id = pitem->stack_id; - tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; - free (pdatanode); + + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + tem = tempnode; + tempip_addr = tempdata->item.ipdata.addr; + tempip_masklen = tempdata->item.ipdata.masklen; + if (ip_masklen < tempip_masklen) + { + continue; + } + + /*if already exist, just return success */ + if (ip_maskv == MASK_V(tempip_addr, tempip_masklen)) + { + /* Optimize log */ + NSSOC_LOGDBG + ("insert ip=*.*.%u.%u, mask=0x%x, stack_id=%d, exist orgid=%d", + FUZZY_IP_VAR(&pitem->ipdata.addr), pitem->ipdata.masklen, + pitem->stack_id, tempdata->item.stack_id); + /* Optimize log */ + + tempdata->item.stack_id = pitem->stack_id; + tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_SUCCESS; + } + hlist_add_before(&(pdatanode->rdnode), tempnode); + return NSTACK_RD_SUCCESS; - } - hlist_add_before (&(pdatanode->rdnode), tempnode); + + } + hlist_add_after(tem, &(pdatanode->rdnode)); + return NSTACK_RD_SUCCESS; - } - hlist_add_after (tem, &(pdatanode->rdnode)); - return NSTACK_RD_SUCCESS; + } /* *find stackid by ip - *input ip must netorder + *input ip must be network order */ -int -nstack_rd_ip_item_find (nstack_rd_list * hlist, void *rdkey, void *outitem) +int nstack_rd_ip_item_find(nstack_rd_list * hlist, void *rdkey, void *outitem) { - struct hlist_node *tempnode = NULL; - nstack_rd_node *tempdata = NULL; - unsigned int tempip_addr = 0; - unsigned int tempip_masklen = 0; - nstack_rd_key *key = (nstack_rd_key *) rdkey; - rd_data_item *pitem = (rd_data_item *) outitem; - unsigned int ip_addr = 0; - /*need to convert to local order */ - ip_addr = ntohl (key->ip_addr); - - hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) - { - tempip_addr = tempdata->item.ipdata.addr; - tempip_masklen = tempdata->item.ipdata.masklen; - /*if already exist, just return success */ - if (MASK_V (ip_addr, tempip_masklen) == - MASK_V (tempip_addr, tempip_masklen)) - { - NSTACK_RD_IP_ITEM_COPY (pitem, &(tempdata->item)); - return NSTACK_RD_SUCCESS; - } - } + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + unsigned int tempip_addr = 0; + unsigned int tempip_masklen = 0; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + rd_data_item *pitem = (rd_data_item *) outitem; + unsigned int ip_addr = key->ip_addr; - NSSOC_LOGDBG ("ip=%u.%u.%u.%u item not found", ip4_addr4_16 (&ip_addr), - ip4_addr3_16 (&ip_addr), - ip4_addr2_16 (&ip_addr), ip4_addr1_16 (&ip_addr)); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + tempip_addr = tempdata->item.ipdata.addr; + tempip_masklen = tempdata->item.ipdata.masklen; + /*if already exist, just return success */ + if (MASK_V(ip_addr, tempip_masklen) == + MASK_V(tempip_addr, tempip_masklen)) + { + NSTACK_RD_IP_ITEM_COPY(pitem, &(tempdata->item)); + return NSTACK_RD_SUCCESS; + } + } - return NSTACK_RD_FAIL; + /* Optimize log */ + NSSOC_LOGDBG("ip=*.*.%u.%u item not found", FUZZY_IP_VAR(&ip_addr)); + + return NSTACK_RD_FAIL; } /***************************************************************************** @@ -180,86 +181,130 @@ nstack_rd_ip_item_find (nstack_rd_list * hlist, void *rdkey, void *outitem) * Calls : * Called By : *****************************************************************************/ -int -nstack_rd_ip_item_age (nstack_rd_list * hlist) +int nstack_rd_ip_item_age(nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF("nstack rd ip age begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + /*if agetime equal 0, remove it */ + if (tempdata->item.agetime <= 0) + { + if (prevdata) + { + /* Optimize log */ + NSSOC_LOGDBG + ("stackid=%d, addrip=*.*.%u.%u, masklen=0x%x was aged", + tempdata->item.stack_id, + FUZZY_IP_VAR(&tempdata->item.ipdata.addr), + tempdata->item.ipdata.masklen); + + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + prevdata = tempdata; + prevnode = tempnode; + } + else + { + tempdata->item.agetime--; + } + } + if (prevdata) + { + if (tempdata) + { + /* Optimize log */ + NSSOC_LOGDBG + ("stackid:%d, addrip:*.*.%u.%u, masklen:0x%x was last aged", + tempdata->item.stack_id, + FUZZY_IP_VAR(&tempdata->item.ipdata.addr), + tempdata->item.ipdata.masklen); + } + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + NSSOC_LOGINF("nstack rd ip age end"); + return NSTACK_RD_SUCCESS; +} + +void nstack_rd_ip_item_clean(nstack_rd_list * hlist) { - struct hlist_node *tempnode = NULL; - nstack_rd_node *tempdata = NULL; - nstack_rd_node *prevdata = NULL; - struct hlist_node *prevnode = NULL; - NSSOC_LOGINF ("nstack rd ip age begin"); - hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) - { - /*if agetime equal 0, remove it */ - if (tempdata->item.agetime <= 0) - { + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF("nstack rd ip item clean begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { if (prevdata) - { + { NSSOC_LOGDBG - ("stackid:%d, addrip:%u.%u.%u.%u, masklen:0x%x was aged", - tempdata->item.stack_id, - ip4_addr4_16 (&tempdata->item.ipdata.addr), - ip4_addr3_16 (&tempdata->item.ipdata.addr), - ip4_addr2_16 (&tempdata->item.ipdata.addr), - ip4_addr1_16 (&tempdata->item.ipdata.addr), - tempdata->item.ipdata.masklen); - - hlist_del_init (prevnode); - free (prevdata); - } + ("stackid=%d, addrip=*.*.%u.%u, masklen=0x%x was aged", + tempdata->item.stack_id, + FUZZY_IP_VAR(&tempdata->item.ipdata.addr), + tempdata->item.ipdata.masklen); + + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + prevdata = tempdata; prevnode = tempnode; - } - else - { - tempdata->item.agetime--; - } - } - if (prevdata) + } + if (prevdata) { - if (tempdata) + if (tempdata) { - NSSOC_LOGDBG - ("stackid:%d, addrip:%u.%u.%u.%u, masklen:0x%x was last aged", - tempdata->item.stack_id, - ip4_addr4_16 (&tempdata->item.ipdata.addr), - ip4_addr3_16 (&tempdata->item.ipdata.addr), - ip4_addr2_16 (&tempdata->item.ipdata.addr), - ip4_addr1_16 (&tempdata->item.ipdata.addr), - tempdata->item.ipdata.masklen); + NSSOC_LOGDBG + ("stackid:%d, addrip:*.*.%u.%u, masklen:0x%x was last aged", + tempdata->item.stack_id, + FUZZY_IP_VAR(&tempdata->item.ipdata.addr), + tempdata->item.ipdata.masklen); } - hlist_del_init (prevnode); - free (prevdata); + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ } - NSSOC_LOGINF ("nstack rd ip age end"); - return NSTACK_RD_SUCCESS; + NSSOC_LOGINF("nstack rd ip item clean end"); +} + +static int nstack_get_stackid_byname(char *name) +{ + int stacknum = g_rd_local_data->stack_num; + int iindex = 0; + nstack_rd_stack_info *pstack = NULL; + for (iindex = 0; iindex < stacknum; iindex++) + { + pstack = &(g_rd_local_data->pstack_info[iindex]); + if (0 == strcmp(pstack->name, name)) + { + return pstack->stack_id; + } + } + return -1; } /* *find stackid by spec ip(multicast ip) - *input ip must netorder + *input ip must be network order */ -int -nstack_rd_ip_spec (void *rdkey) +int nstack_rd_ip_spec(void *rdkey) { - nstack_rd_key *key = (nstack_rd_key *) rdkey; - unsigned int ip_addr = 0; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + unsigned int ip_addr = 0; - ip_addr = ntohl (key->ip_addr); + ip_addr = (key->ip_addr); - if (rd_ismulticast (ip_addr)) + if (rd_ismulticast(ip_addr)) { - if (-1 == g_multi_stackid) + if (-1 == g_multi_stackid) { - g_multi_stackid = nstack_get_stackid_byname (NSTACK_IP_MLSTACKID); + g_multi_stackid = nstack_get_stackid_byname(RD_STACKPOOL_NAME); } - return g_multi_stackid; + return g_multi_stackid; } - return -1; -} - -int -nstack_rd_ip_default (void *rdkey) -{ - return NSTACK_GET_STACK (0); + return -1; } diff --git a/src/nSocket/nstack_rd/nstack_rd_ip.h b/src/nSocket/nstack_rd/nstack_rd_ip.h index d64956d..b3abee3 100644 --- a/src/nSocket/nstack_rd/nstack_rd_ip.h +++ b/src/nSocket/nstack_rd/nstack_rd_ip.h @@ -17,6 +17,8 @@ #ifndef __NSTACK_RD_IP_H #define __NSTACK_RD_IP_H +#include "nstack_rd_priv.h" + #define NSTACK_RD_IP_ITEM_COPY(destitem, srcitem){ \ (destitem)->agetime = (srcitem)->agetime; \ (destitem)->stack_id = (srcitem)->stack_id; \ @@ -27,12 +29,12 @@ (destitem)->ipdata.resev[1] = (srcitem)->ipdata.resev[1]; \ } -int nstack_rd_ipdata_cpy (void *destdata, void *srcdata); -int nstack_rd_ip_item_insert (nstack_rd_list * hlist, void *rditem); -int nstack_rd_ip_item_find (nstack_rd_list * hlist, void *rdkey, - void *outitem); -int nstack_rd_ip_item_age (nstack_rd_list * hlist); -int nstack_rd_ip_spec (void *rdkey); -int nstack_rd_ip_default (void *rdkey); +int nstack_rd_ip_data_cpy(void *destdata, void *srcdata); +int nstack_rd_ip_item_insert(nstack_rd_list * hlist, void *rditem); +int nstack_rd_ip_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem); +int nstack_rd_ip_item_age(nstack_rd_list * hlist); +void nstack_rd_ip_item_clean(nstack_rd_list * hlist); +int nstack_rd_ip_spec(void *rdkey); #endif diff --git a/src/nSocket/nstack_rd/nstack_rd_ip6.c b/src/nSocket/nstack_rd/nstack_rd_ip6.c new file mode 100644 index 0000000..dde201d --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_ip6.c @@ -0,0 +1,261 @@ +/* +* +* 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 <stdlib.h> +#include <arpa/inet.h> +#include "nstack_rd_data.h" +#include "nstack_rd.h" +#include "nstack_rd_priv.h" +#include "nstack_rd_ip6.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nstack_ip_addr.h" + +inline static const char *ip6_ntoa(const ip6_addr_t * addr) +{ +#define IP6_NTOA_NUM (1 << 3) +#define IP6_NTOA_LEN 46 + static __thread char ip6_ntoa_buf[IP6_NTOA_NUM][IP6_NTOA_LEN]; + static __thread unsigned int ip6_ntoa_index = 0; + + char *buf = ip6_ntoa_buf[(ip6_ntoa_index++) & (IP6_NTOA_NUM - 1)]; + return inet_ntop(AF_INET, addr, buf, IP6_NTOA_LEN); +} + +int nstack_rd_ip6_data_cpy(void *destdata, void *srcdata) +{ + rd_data_item *pitem = (rd_data_item *) destdata; + rd_route_data *pdata = (rd_route_data *) srcdata; + + pitem->type = pdata->type; + pitem->ip6data = pdata->ip6data; + return NSTACK_RD_SUCCESS; +} + +/* + * Add an ip segment to the list and sort it in descending order of ip mask length + * If the list already exists in the same list of ip side, then stack_id update + * ip is network byte order + */ +/*vars are used in macro*/ +int nstack_rd_ip6_item_insert(nstack_rd_list * hlist, void *rditem) +{ + nstack_rd_node *pdatanode = NULL; + nstack_rd_node *tempdata = NULL; + struct hlist_node *tempnode = NULL; + struct hlist_node *tem = NULL; + rd_data_item *pitem = (rd_data_item *) rditem; + char buf[52]; + + NSSOC_LOGDBG("stackid:%d, ip6addr:%s masklen:0x%x was inserted", + pitem->stack_id, inet_ntop(AF_INET6, &pitem->ip6data.addr, + buf, sizeof(buf)), + pitem->ip6data.masklen); + + pdatanode = (nstack_rd_node *) malloc(sizeof(nstack_rd_node)); /*this function is necessary */ + if (!pdatanode) + { + NSSOC_LOGERR("nstack rd item malloc fail"); + return NSTACK_RD_FAIL; + } + + int retVal = memset_s(pdatanode, sizeof(nstack_rd_node), 0, + sizeof(nstack_rd_node)); + if (EOK != retVal) + { + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_FAIL; + } + + INIT_HLIST_NODE(&pdatanode->rdnode); + pdatanode->item = *pitem; + + if (hlist_empty(&(hlist->headlist))) + { + hlist_add_head(&(pdatanode->rdnode), &(hlist->headlist)); + + return NSTACK_RD_SUCCESS; + + } + + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + tem = tempnode; + if (pitem->ip6data.masklen < tempdata->item.ip6data.masklen) + { + continue; + } + + /*if already exist, just return success */ + if (pitem->ip6data.masklen == tempdata->item.ip6data.masklen && + ip6_addr_match(&pitem->ip6data.addr, + &tempdata->item.ip6data.addr, + pitem->ip6data.masklen)) + { + NSSOC_LOGDBG + ("insert ip6:%s, mask:0x%x, stack_id:%d, exist orgid:%d", + inet_ntop(AF_INET6, &pitem->ip6data.addr, buf, + sizeof(buf)), pitem->ip6data.masklen, + pitem->stack_id, tempdata->item.stack_id); + + tempdata->item.stack_id = pitem->stack_id; + tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_SUCCESS; + } + hlist_add_before(&(pdatanode->rdnode), tempnode); + + return NSTACK_RD_SUCCESS; + + } + hlist_add_after(tem, &(pdatanode->rdnode)); + + return NSTACK_RD_SUCCESS; + +} + +int nstack_rd_ip6_item_age(nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + char buf[46]; + + NSSOC_LOGINF("nstack rd ip age begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + /*if agetime equal 0, remove it */ + if (tempdata->item.agetime <= 0) + { + if (prevdata) + { + NSSOC_LOGDBG("stackid:%d, addrip6:%s, masklen:0x%x was aged", + tempdata->item.stack_id, + inet_ntop(AF_INET6, + &tempdata->item.ip6data.addr, buf, + sizeof(buf)), + tempdata->item.ip6data.masklen); + + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + prevdata = tempdata; + prevnode = tempnode; + } + else + { + tempdata->item.agetime--; + } + } + if (prevdata) + { + if (tempdata) + { + NSSOC_LOGDBG + ("stackid:%d, addrip6:%s, masklen:0x%x was last aged", + tempdata->item.stack_id, inet_ntop(AF_INET6, + &tempdata->item. + ip6data.addr, buf, + sizeof(buf)), + tempdata->item.ip6data.masklen); + } + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + + NSSOC_LOGINF("nstack rd ip age end"); + return NSTACK_RD_SUCCESS; +} + +void nstack_rd_ip6_item_clean(nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + char buf[46]; + + NSSOC_LOGINF("nstack rd ip clean begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (prevdata) + { + NSSOC_LOGDBG("stackid:%d, addrip6:%s, masklen:0x%x was aged", + tempdata->item.stack_id, + inet_ntop(AF_INET6, &tempdata->item.ip6data.addr, + buf, sizeof(buf)), + tempdata->item.ip6data.masklen); + + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + + prevdata = tempdata; + prevnode = tempnode; + } + if (prevdata) + { + if (tempdata) + { + NSSOC_LOGDBG + ("stackid:%d, addrip6:%s, masklen:0x%x was last aged", + tempdata->item.stack_id, inet_ntop(AF_INET6, + &tempdata->item. + ip6data.addr, buf, + sizeof(buf)), + tempdata->item.ip6data.masklen); + } + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + + NSSOC_LOGINF("nstack rd ip clean end"); +} + +int nstack_rd_ip6_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + char buf[46]; + + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + rd_data_item *tempitem = &tempdata->item; + + /*if already exist, just return success */ + if (ip6_addr_match + ((struct ip6_addr *) &key->in6_addr, &tempitem->ip6data.addr, + tempitem->ip6data.masklen)) + { + *(rd_data_item *) outitem = *tempitem; + return NSTACK_RD_SUCCESS; + } + } + + NSSOC_LOGDBG("ip6=%s item not found", + inet_ntop(AF_INET6, &key->in6_addr, buf, sizeof(buf))); + + return NSTACK_RD_FAIL; +} + +int nstack_rd_ip6_spec(void *rdkey) +{ + return -1; +} diff --git a/src/nSocket/nstack_rd/nstack_rd_ip6.h b/src/nSocket/nstack_rd/nstack_rd_ip6.h new file mode 100644 index 0000000..2934bb3 --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_ip6.h @@ -0,0 +1,25 @@ +/* +* +* 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. +*/ + +#define __NSTACK_RD_IP6_H + +int nstack_rd_ip6_data_cpy(void *destdata, void *srcdata); +int nstack_rd_ip6_item_insert(nstack_rd_list * hlist, void *rditem); +int nstack_rd_ip6_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem); +int nstack_rd_ip6_item_age(nstack_rd_list * hlist); +void nstack_rd_ip6_item_clean(nstack_rd_list * hlist); +int nstack_rd_ip6_spec(void *rdkey); diff --git a/src/nSocket/nstack_rd/nstack_rd_proto.c b/src/nSocket/nstack_rd/nstack_rd_proto.c index 81246c0..e1c58e2 100644 --- a/src/nSocket/nstack_rd/nstack_rd_proto.c +++ b/src/nSocket/nstack_rd/nstack_rd_proto.c @@ -18,107 +18,111 @@ #include <arpa/inet.h> #include "nstack_rd_data.h" #include "nstack_rd.h" -#include "nstack_rd_init.h" #include "nstack_rd_priv.h" #include "nstack_rd_proto.h" #include "nstack_log.h" #include "nstack_securec.h" -#include "common_mem_common.h" /*copy rd data*/ -int -nstack_rd_proto_cpy (void *destdata, void *srcdata) +int nstack_rd_proto_data_cpy(void *destdata, void *srcdata) { - rd_data_item *pitem = (rd_data_item *) destdata; - rd_route_data *pdata = (rd_route_data *) srcdata; - pitem->type = pdata->type; - pitem->proto_type = pdata->proto_type; - return NSTACK_RD_SUCCESS; + rd_data_item *pitem = (rd_data_item *) destdata; + rd_route_data *pdata = (rd_route_data *) srcdata; + + pitem->type = pdata->type; + pitem->proto_data.value = pdata->proto_data.value; + pitem->proto_data.attr = pdata->proto_data.attr; + return NSTACK_RD_SUCCESS; } /* * Add an ip segment to the list and sort it in descending order of ip mask length * If the list already exists in the same list of ip side, then stack_id update - *ip is local byteorder + *ip is network byte order */ -int -nstack_rd_proto_item_insert (nstack_rd_list * hlist, void *rditem) +/*vars are used in macro*/ +int nstack_rd_proto_item_insert(nstack_rd_list * hlist, void *rditem) { - nstack_rd_node *pdatanode = NULL; - nstack_rd_node *tempdata = NULL; - struct hlist_node *tempnode = NULL; - rd_data_item *pitem = (rd_data_item *) rditem; + nstack_rd_node *pdatanode = NULL; + nstack_rd_node *tempdata = NULL; + struct hlist_node *tempnode = NULL; + rd_data_item *pitem = (rd_data_item *) rditem; - NSSOC_LOGDBG ("stackid:%d, protocol type:%d was inserted", pitem->stack_id, - pitem->proto_type); + NSSOC_LOGDBG("stackid:%d, proto value:%u proto attr:%u was inserted", + pitem->stack_id, pitem->proto_data.value, + pitem->proto_data.attr); - pdatanode = (nstack_rd_node *) malloc (sizeof (nstack_rd_node)); - if (!pdatanode) + pdatanode = (nstack_rd_node *) malloc(sizeof(nstack_rd_node)); /*this function is necessary */ + if (!pdatanode) { - NSSOC_LOGERR ("nstack rd item malloc fail"); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("nstack rd item malloc fail"); + return NSTACK_RD_FAIL; } - int retVal = - MEMSET_S (pdatanode, sizeof (nstack_rd_node), 0, sizeof (nstack_rd_node)); - if (EOK != retVal) + /* add return value check */ + int retVal = memset_s(pdatanode, sizeof(nstack_rd_node), 0, + sizeof(nstack_rd_node)); + if (EOK != retVal) { - NSSOC_LOGERR ("MEMSET_S failed]retVal=%d", retVal); - free (pdatanode); - return NSTACK_RD_FAIL; + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_FAIL; } - INIT_HLIST_NODE (&pdatanode->rdnode); - NSTACK_RD_PROTO_ITEM_COPY (&(pdatanode->item), pitem); - if (hlist_empty (&(hlist->headlist))) + INIT_HLIST_NODE(&pdatanode->rdnode); + NSTACK_RD_PROTO_ITEM_COPY(&(pdatanode->item), pitem); + + if (hlist_empty(&(hlist->headlist))) { - hlist_add_head (&(pdatanode->rdnode), &(hlist->headlist)); + hlist_add_head(&(pdatanode->rdnode), &(hlist->headlist)); - return NSTACK_RD_SUCCESS; + return NSTACK_RD_SUCCESS; } - hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) - { - if (tempdata->item.proto_type == pitem->proto_type) - - { - tempdata->item.stack_id = pitem->stack_id; - tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; - free (pdatanode); - return NSTACK_RD_SUCCESS; - } - } - hlist_add_head (&(pdatanode->rdnode), &(hlist->headlist)); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (tempdata->item.proto_data.value == pitem->proto_data.value) + { + NSSOC_LOGDBG + ("find duplicate node, proto value:%u, old stack_id:%d, new stack_id:%d", + pitem->proto_data.value, tempdata->item.stack_id, + pitem->stack_id); + tempdata->item.stack_id = pitem->stack_id; + tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_SUCCESS; + } + } + hlist_add_head(&(pdatanode->rdnode), &(hlist->headlist)); - return NSTACK_RD_SUCCESS; + return NSTACK_RD_SUCCESS; } /* *find stackid by ip - *input ip must netorder + *input ip must be network order */ -int -nstack_rd_proto_item_find (nstack_rd_list * hlist, void *rdkey, void *outitem) +int nstack_rd_proto_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem) { - struct hlist_node *tempnode = NULL; - nstack_rd_node *tempdata = NULL; - nstack_rd_key *key = (nstack_rd_key *) rdkey; - rd_data_item *pitem = (rd_data_item *) outitem; - hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) - { - - /*if already exist, just return success */ - if (tempdata->item.proto_type == key->proto_type) - - { - NSTACK_RD_PROTO_ITEM_COPY (pitem, &(tempdata->item)); - return NSTACK_RD_SUCCESS; - } - } + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + rd_data_item *pitem = (rd_data_item *) outitem; - NSSOC_LOGDBG ("protocol type item not found", key->proto_type); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (tempdata->item.proto_data.value == key->proto) + { + NSTACK_RD_PROTO_ITEM_COPY(pitem, &(tempdata->item)); + return NSTACK_RD_SUCCESS; + } + } - return NSTACK_RD_FAIL; + /* Optimize log */ + NSSOC_LOGDBG("proto:%u item not found", key->proto); + + return NSTACK_RD_FAIL; } /***************************************************************************** @@ -130,61 +134,92 @@ nstack_rd_proto_item_find (nstack_rd_list * hlist, void *rdkey, void *outitem) * Calls : * Called By : *****************************************************************************/ -int -nstack_rd_proto_item_age (nstack_rd_list * hlist) +int nstack_rd_proto_item_age(nstack_rd_list * hlist) { - struct hlist_node *tempnode = NULL; - nstack_rd_node *tempdata = NULL; - nstack_rd_node *prevdata = NULL; - struct hlist_node *prevnode = NULL; - NSSOC_LOGINF ("nstack rd ip age begin"); - hlist_for_each_entry (tempdata, tempnode, &(hlist->headlist), rdnode) - { - /*if agetime equal 0, remove it */ - if (tempdata->item.agetime <= 0) - { + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF("nstack rd proto age begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + /*if agetime equal 0, remove it */ + if (tempdata->item.agetime <= 0) + { + if (prevdata) + { + /* Optimize log */ + NSSOC_LOGDBG("stackid=%d, proto:%u was aged", + tempdata->item.stack_id, + tempdata->item.proto_data.value); + + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + prevdata = tempdata; + prevnode = tempnode; + } + else + { + tempdata->item.agetime--; + } + } + if (prevdata) + { + if (tempdata) + { + /* Optimize log */ + NSSOC_LOGDBG("stackid:%d, proto:%u was last aged", + tempdata->item.stack_id, + tempdata->item.proto_data.value); + } + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + NSSOC_LOGINF("nstack rd proto age end"); + return NSTACK_RD_SUCCESS; +} + +void nstack_rd_proto_item_clean(nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF("nstack rd proto item clean begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { if (prevdata) - { - NSSOC_LOGDBG ("stackid:%d, protocol type was aged", - tempdata->item.stack_id, tempdata->item.proto_type); + { + NSSOC_LOGDBG("stackid=%d, proto:%u was cleaned", + tempdata->item.stack_id, + tempdata->item.proto_data.value); + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } - hlist_del_init (prevnode); - free (prevdata); - } prevdata = tempdata; prevnode = tempnode; - } - else - { - tempdata->item.agetime--; - } - } - if (prevdata) + } + if (prevdata) { - if (tempdata) + if (tempdata) { - NSSOC_LOGDBG ("stackid:%d, protocol type was aged", - tempdata->item.stack_id, tempdata->item.proto_type); + NSSOC_LOGDBG("stackid=%d, proto:%u was last cleaned", + tempdata->item.stack_id, + tempdata->item.proto_data.value); } - hlist_del_init (prevnode); - free (prevdata); + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ } - NSSOC_LOGINF ("nstack rd ip age end"); - return NSTACK_RD_SUCCESS; + NSSOC_LOGINF("nstack rd proto item clean end"); } /* *find stackid by spec ip(multicast ip) - *input ip must netorder + *input ip must be network order */ -int -nstack_rd_proto_spec (void *rdkey) -{ - return -1; -} - -int -nstack_rd_proto_default (void *rdkey) +int nstack_rd_proto_spec(void *rdkey) { - return -1; + return -1; } diff --git a/src/nSocket/nstack_rd/nstack_rd_proto.h b/src/nSocket/nstack_rd/nstack_rd_proto.h index f3b0311..e8a573e 100644 --- a/src/nSocket/nstack_rd/nstack_rd_proto.h +++ b/src/nSocket/nstack_rd/nstack_rd_proto.h @@ -16,20 +16,23 @@ #ifndef __NSTACK_RD_PROTO_H #define __NSTACK_RD_PROTO_H -/* *INDENT-OFF* */ + +#include "nstack_rd_priv.h" + #define NSTACK_RD_PROTO_ITEM_COPY(destitem, srcitem){ \ (destitem)->agetime = (srcitem)->agetime; \ (destitem)->stack_id = (srcitem)->stack_id; \ (destitem)->type = (srcitem)->type; \ - (destitem)->proto_type = (srcitem)->proto_type; \ + (destitem)->proto_data.value = (srcitem)->proto_data.value; \ + (destitem)->proto_data.attr = (srcitem)->proto_data.attr; \ } -/* *INDENT-ON* */ -int nstack_rd_proto_cpy (void *destdata, void *srcdata); -int nstack_rd_proto_item_insert (nstack_rd_list * hlist, void *rditem); -int nstack_rd_proto_item_find (nstack_rd_list * hlist, void *rdkey, - void *outitem); -int nstack_rd_proto_item_age (nstack_rd_list * hlist); -int nstack_rd_proto_spec (void *rdkey); -int nstack_rd_proto_default (void *rdkey); -#endif /* */ +int nstack_rd_proto_data_cpy(void *destdata, void *srcdata); +int nstack_rd_proto_item_insert(nstack_rd_list * hlist, void *rditem); +int nstack_rd_proto_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem); +int nstack_rd_proto_item_age(nstack_rd_list * hlist); +void nstack_rd_proto_item_clean(nstack_rd_list * hlist); +int nstack_rd_proto_spec(void *rdkey); + +#endif diff --git a/src/nSocket/nstack_rd/nstack_rd_type.c b/src/nSocket/nstack_rd/nstack_rd_type.c new file mode 100644 index 0000000..c5f440e --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_type.c @@ -0,0 +1,229 @@ +/* +* +* 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 <stdlib.h> +#include <arpa/inet.h> +#include "nstack_rd_data.h" +#include "nstack_rd.h" +#include "nstack_rd_priv.h" +#include "nstack_rd_type.h" +#include "nstack_log.h" +#include "nstack_securec.h" + +/*copy rd data*/ +int nstack_rd_type_data_cpy(void *destdata, void *srcdata) +{ + rd_data_item *pitem = (rd_data_item *) destdata; + rd_route_data *pdata = (rd_route_data *) srcdata; + + pitem->type = pdata->type; + pitem->type_data.value = pdata->type_data.value; + pitem->type_data.attr = pdata->type_data.attr; + pitem->type_data.reserved[0] = pdata->type_data.reserved[0]; + pitem->type_data.reserved[1] = pdata->type_data.reserved[1]; + pitem->type_data.reserved[2] = pdata->type_data.reserved[2]; + pitem->type_data.reserved[3] = pdata->type_data.reserved[3]; + return NSTACK_RD_SUCCESS; +} + +/* + * Add an ip segment to the list and sort it in descending order of ip mask length + * If the list already exists in the same list of ip side, then stack_id update + *ip is network byte order + */ +/*vars are used in macro*/ +int nstack_rd_type_item_insert(nstack_rd_list * hlist, void *rditem) +{ + nstack_rd_node *pdatanode = NULL; + nstack_rd_node *tempdata = NULL; + struct hlist_node *tempnode = NULL; + rd_data_item *pitem = (rd_data_item *) rditem; + + NSSOC_LOGDBG("stackid:%d, type value:%u type attr:%u was inserted", + pitem->stack_id, pitem->type_data.value, + pitem->type_data.attr); + + pdatanode = (nstack_rd_node *) malloc(sizeof(nstack_rd_node)); /*this function is necessary */ + if (!pdatanode) + { + NSSOC_LOGERR("nstack rd item malloc fail"); + return NSTACK_RD_FAIL; + } + /* add return value check */ + int retVal = memset_s(pdatanode, sizeof(nstack_rd_node), 0, + sizeof(nstack_rd_node)); + if (EOK != retVal) + { + NSSOC_LOGERR("memset_s failed]retVal=%d", retVal); + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_FAIL; + } + INIT_HLIST_NODE(&pdatanode->rdnode); + NSTACK_RD_TYPE_ITEM_COPY(&(pdatanode->item), pitem); + + if (hlist_empty(&(hlist->headlist))) + { + hlist_add_head(&(pdatanode->rdnode), &(hlist->headlist)); + + return NSTACK_RD_SUCCESS; + + } + + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (tempdata->item.type_data.value == pitem->type_data.value) + { + NSSOC_LOGDBG + ("find duplicate node, type value:%u, old stack_id:%d, new stack_id:%d", + pitem->type_data.value, tempdata->item.stack_id, + pitem->stack_id); + tempdata->item.stack_id = pitem->stack_id; + tempdata->item.agetime = NSTACK_RD_AGETIME_MAX; + free(pdatanode); /*this function is necessary */ + return NSTACK_RD_SUCCESS; + } + } + hlist_add_head(&(pdatanode->rdnode), &(hlist->headlist)); + + return NSTACK_RD_SUCCESS; + +} + +/* + *find stackid by ip + *input ip must be network order + */ +int nstack_rd_type_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_key *key = (nstack_rd_key *) rdkey; + rd_data_item *pitem = (rd_data_item *) outitem; + + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (tempdata->item.type_data.value == key->socket_type) + { + NSTACK_RD_TYPE_ITEM_COPY(pitem, &(tempdata->item)); + return NSTACK_RD_SUCCESS; + } + } + + /* Optimize log */ + NSSOC_LOGDBG("socket type:%u item not found", key->socket_type); + + return NSTACK_RD_FAIL; +} + +/***************************************************************************** +* Prototype : nstack_rd_ip_item_age +* Description : delete the ip item that have not been add again for one time +* Input : nstack_rd_list *hlist +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nstack_rd_type_item_age(nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF("nstack rd type age begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + /*if agetime equal 0, remove it */ + if (tempdata->item.agetime <= 0) + { + if (prevdata) + { + /* Optimize log */ + NSSOC_LOGDBG("stackid=%d, type:%u was aged", + tempdata->item.stack_id, + tempdata->item.type_data.value); + + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + prevdata = tempdata; + prevnode = tempnode; + } + else + { + tempdata->item.agetime--; + } + } + if (prevdata) + { + if (tempdata) + { + /* Optimize log */ + NSSOC_LOGDBG("stackid:%d, type:%u was last aged", + tempdata->item.stack_id, + tempdata->item.type_data.value); + } + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + NSSOC_LOGINF("nstack rd type age end"); + return NSTACK_RD_SUCCESS; +} + +void nstack_rd_type_item_clean(nstack_rd_list * hlist) +{ + struct hlist_node *tempnode = NULL; + nstack_rd_node *tempdata = NULL; + nstack_rd_node *prevdata = NULL; + struct hlist_node *prevnode = NULL; + NSSOC_LOGINF("nstack rd type item clean begin"); + hlist_for_each_entry(tempdata, tempnode, &(hlist->headlist), rdnode) + { + if (prevdata) + { + NSSOC_LOGDBG("stackid=%d, type:%u was cleaned", + tempdata->item.stack_id, + tempdata->item.type_data.value); + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + + prevdata = tempdata; + prevnode = tempnode; + } + if (prevdata) + { + if (tempdata) + { + NSSOC_LOGDBG("stackid=%d, type:%u was last cleaned", + tempdata->item.stack_id, + tempdata->item.type_data.value); + } + hlist_del_init(prevnode); + free(prevdata); /*this function is necessary */ + } + NSSOC_LOGINF("nstack rd type item clean end"); +} + +/* + *find stackid by spec ip(multicast ip) + *input ip must be network order + */ +int nstack_rd_type_spec(void *rdkey) +{ + return -1; +} diff --git a/src/nSocket/nstack_rd/nstack_rd_type.h b/src/nSocket/nstack_rd/nstack_rd_type.h new file mode 100644 index 0000000..d50fa87 --- /dev/null +++ b/src/nSocket/nstack_rd/nstack_rd_type.h @@ -0,0 +1,42 @@ +/* +* +* 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 __NSTACK_RD_TYPE_H +#define __NSTACK_RD_TYPE_H + +#include "nstack_rd_priv.h" + +#define NSTACK_RD_TYPE_ITEM_COPY(destitem, srcitem){ \ + (destitem)->agetime = (srcitem)->agetime; \ + (destitem)->stack_id = (srcitem)->stack_id; \ + (destitem)->type = (srcitem)->type; \ + (destitem)->type_data.value = (srcitem)->type_data.value; \ + (destitem)->type_data.attr = (srcitem)->type_data.attr; \ + (destitem)->type_data.reserved[0] = (srcitem)->type_data.reserved[0]; \ + (destitem)->type_data.reserved[1] = (srcitem)->type_data.reserved[1]; \ + (destitem)->type_data.reserved[2] = (srcitem)->type_data.reserved[2]; \ + (destitem)->type_data.reserved[3] = (srcitem)->type_data.reserved[3]; \ +} + +int nstack_rd_type_data_cpy(void *destdata, void *srcdata); +int nstack_rd_type_item_insert(nstack_rd_list * hlist, void *rditem); +int nstack_rd_type_item_find(nstack_rd_list * hlist, void *rdkey, + void *outitem); +int nstack_rd_type_item_age(nstack_rd_list * hlist); +void nstack_rd_type_item_clean(nstack_rd_list * hlist); +int nstack_rd_type_spec(void *rdkey); + +#endif |