From a826fe833d3f2a8fe2673fa05811fe1a22baf045 Mon Sep 17 00:00:00 2001 From: charan makkina Date: Tue, 30 Apr 2019 17:40:53 +0530 Subject: Feature: 19.04 part 1 Change-Id: Ibba924b8deca1f246b9dcb12d89d085b6fd33046 Signed-off-by: charan makkina --- src/nSocket/nstack/nstack_socket.c | 4464 +++++++++++++++++++----------------- 1 file changed, 2386 insertions(+), 2078 deletions(-) (limited to 'src/nSocket/nstack/nstack_socket.c') 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 +#include + #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 +#include #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 ("addrlenops) + /* 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) - { - retval = ns_success; - nstack_set_bind_ret (fdInf, fdInf->rmidx, NSTACK_BIND_SUCCESS); - } - else + /*if alloc failed */ + nstack_each_mod_ops(modInx, ops) { - 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(bind, fd, addr, addrlen); - NSTACK_INIT_CHECK_RET (accept, fd, addr, addr_len); + NSSOC_LOGINF("(sockfd=%d, addr=%p, addrlen=%u) [Caller]", fd, addr, + addrlen); - NSSOC_LOGINF ("(sockfd=%d, addr=%p, addrlen=%p) [Caller]", fd, addr, - addr_len); - if (fd < 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)) + { + nstack_set_errno(EINVAL); + NSSOC_LOGERR("invalid input]fd=%d,addr=%p,len=0x%x [return]", fd, + addr, addrlen); + return -1; + } + + /*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)) { - nstack_set_errno (EBADF); - NSSOC_LOGERR ("fd is invalid]fd=%d [return]", fd); - return -1; + 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); } - 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); + NSTACK_FD_LINUX_CHECK_RETURN(fd, bind, fdInf, (fd, addr, addrlen)); - if (addr) + 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; + } + + /*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(EAFNOSUPPORT); + NSSOC_LOGERR("not surport]fd=%d,domain=%d,[return]", fd, + addr->sa_family); + 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))) + /* 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 accept fd=%d no module select, or bind/listen fail [return]", - fd); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + nstack_set_errno(EINVAL); + NSPOL_LOGERR("addrlenrmidx); - 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) + + /* for custom socket, choose stack after creating socket. */ + if (fdInf->ops) { - if (errno != EAGAIN) + 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_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_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_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) { - NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (fix_fd), ret); + 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 + { + 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; +} + +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); - if (NULL == accInf) + 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 = &apstfdInf->local_lock; + LOCK_ACCEPT(fd, apstfdInf, local_lock); - 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_EPOLL_FD_CHECK_RET_UNLOCK_ACCEPT(fd, accept, apstfdInf, ENOTSOCK, + local_lock); - if (addr) + if (addr) + { + if ((!addr_len) || (*addr_len == NSTACK_MAX_U32_NUM)) + { + 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 ((!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 ((!addr_len) || (*addr_len == NSTACK_MAX_U32_NUM)) + if (errno != EAGAIN) { - nstack_set_errno (EINVAL); - NSSOC_LOGERR ("nstack accept4 addr_len input error [return]"); - UNLOCK_ACCEPT (fd, local_lock); - return -1; + 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; } - /*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))) +#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; } - else + +#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); + } +#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)); - if (!nstack_is_nstack_sk (fix_fd)) + 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 (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)) + { + 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); + 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)) - { - 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)); - } - } - if (ns_success == retval && selectmod >= 0) + retval = nstack_socket_get_stackid(fdInf, 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)); - /*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_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 */ } - else + 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_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; } - 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); + + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_COMMON(fd, shutdown, fdInf, ENOTSOCK, + local_lock); - if (!fdInf->ops || -1 == fdInf->rlfd) + if (!fdInf->ops || -1 == fdInf->rlfd) { - NSSOC_LOGWAR ("fd=%d,how=%d, shutdown fail [return]", fd, how); - nstack_set_errno (ENOTCONN); - UNLOCK_COMMON (fd, local_lock); - return -1; + 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); - NSSOC_LOGINF ("fd=%d,ret=%d [return]", fd, retval); - UNLOCK_COMMON (fd, local_lock); - return retval; + 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_LOGINF("fd=%d,ret=%d [return]", fd, 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_protoFd (fdInf, modInx); + nstack_each_module(modInx, pMod) + { + tfd = nstack_get_proto_fd(fdInf, modInx); - if (nstack_get_minfd_id (modInx) > tfd - || tfd > nstack_get_maxfd_id (modInx)) - { - continue; - } + /* add tfd rang check */ + 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); - if (0 == - strcmp (nstack_fix_stack_name (), - nstack_get_module_name_by_idx (modInx))) - { - continue; - } +#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; + } - nssct_close (fd, modInx); - NSTACK_CAL_FUN ((&pMod->mops.socket_ops), close, (tfd), curRet); + /* should release resource for kernel */ + continue; + } +#endif - if (-1 == curRet) - { - NSSOC_LOGERR ("failed]module=%s,tfd=%d,errno=%d", - nstack_get_module_name_by_idx (modInx), tfd, errno); - } + 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); + } - 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 ()) - { - return -1; - } - if (nstack_fix_fd_check () - && nstack_fix_fd_check ()(fd, STACK_FD_FUNCALL_CHECK)) + if (fd != nsep_get_manager()->checkEpollFD) { - /*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); + + /* 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); + } + } + } - UNLOCK_CLOSE (local_lock); - ret = - (atomic_dec (&local_lock->fd_ref) > 0 ? 0 : release_fd (fd, local_lock)); + UNLOCK_CLOSE(local_lock); + ret = + (atomic_dec(&local_lock->fd_ref) > + 0 ? 0 : release_fd(fd, local_lock)); - if (-1 == ret) + 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, "SOC", NSLOG_DBG, + "sockfd=%d,buf=%p,len=%zu,flags=%d[Caller]", 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); + NSTACK_FD_LINUX_CHECK_RETURN(fd, send, fdInf, (fd, buf, len, flags)); - NSTACK_FD_LINUX_CHECK (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_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_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, send, fdInf, ENOTSOCK, + local_lock); - if ((!fdInf->ops) || (-1 == fdInf->rlfd)) + 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); + 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); - NSSOC_LOGDBG ("fd=%d,ret=%d [Return]", fd, 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, "SOC", NSLOG_DBG, + "sockfd=%d,buf=%p,len=%zu,flags=%d[Caller]", 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); + NSTACK_FD_LINUX_CHECK_RETURN(fd, recv, fdInf, (fd, buf, len, flags)); - NSTACK_FD_LINUX_CHECK (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_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_EPOLL_FD_CHECK_RET_UNLOCK_RECV(fd, recv, 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, 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, "NSSOC", NSLOG_DBG, - "(fd=%d, buf=%p, count=%zu) [Caller]", fd, buf, count); + NS_LOG_CTRL(LOG_CTRL_READ, NSOCKET, "SOC", NSLOG_DBG, + "fd=%d,buf=%p,count=%zu[Caller]", fd, buf, count); - NSTACK_FD_LINUX_CHECK (fd, read, fdInf, (fd, buf, count)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, read, fdInf, (fd, buf, count)); - 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_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, read, fdInf, EINVAL, + 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, 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, "SOC", NSLOG_DBG, + "fd=%d,iov=%p,count=%d[Caller]", fd, iov, iovcnt); - NS_LOG_CTRL (LOG_CTRL_WRITEV, NSOCKET, "NSSOC", NSLOG_DBG, - "(fd=%d, iov=%p, count=%d) [Caller]", fd, iov, iovcnt); + NSTACK_FD_LINUX_CHECK_RETURN(fd, writev, fdInf, (fd, iov, iovcnt)); - NSTACK_FD_LINUX_CHECK (fd, writev, fdInf, (fd, iov, iovcnt)); + 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, writev, fdInf, EINVAL, - local_lock); + NSTACK_EPOLL_FD_CHECK_RET_UNLOCK_SEND(fd, writev, 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_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, "NSSOC", NSLOG_DBG, - "(fd=%d, iov=%p, count=%d) [Caller]", fd, iov, iovcnt); + NS_LOG_CTRL(LOG_CTRL_READV, NSOCKET, "SOC", NSLOG_DBG, + "fd=%d,iov=%p,count=%d[Caller]", fd, iov, iovcnt); - NSTACK_FD_LINUX_CHECK (fd, readv, fdInf, (fd, iov, iovcnt)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, readv, fdInf, (fd, iov, iovcnt)); - 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_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, readv, 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_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; + + ns_udp_route_Inf udp_route_info; - NSTACK_INIT_CHECK_RET (sendto, fd, buf, len, flags, dest_addr, addrlen); + NSTACK_INIT_CHECK_RET(sendto, 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); + 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_LINUX_CHECK (fd, sendto, fdInf, - (fd, buf, len, flags, dest_addr, addrlen)); + NSTACK_FD_LINUX_CHECK_RETURN(fd, sendto, fdInf, + (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_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_SEND(fd, fdInf, local_lock); - if (fdInf->ops) + 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_EPOLL_FD_CHECK_RET_UNLOCK_RECV (fd, recvfrom, 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, recvfrom, 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, 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_module_info *select_module = get_select_module(); - struct select_entry *entry = NULL; - struct select_module_info *select_module = get_select_module (); - u64_t msec; + NSTACK_INIT_CHECK_RET(select, nfds, readfds, writefds, exceptfds, + timeout); - int i; - - 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); - } - - 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); - } - } + print_select_dbg(nfds, readfds, writefds, exceptfds); - /*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)) - { - 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) + if (op != EPOLL_CTL_DEL) { - 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) - { - *readfds = entry->ready.readset; - } - if (writefds) - { - *writefds = entry->ready.writeset; - } - if (exceptfds) + epi = nsep_find_ep(ep, fd); + switch (op) { - *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_wait, epfd, events, maxevents, timeout); - NSTACK_INIT_CHECK_RET (epoll_create, size); + NSTACK_FD_LINUX_CHECK_RETURN(epfd, epoll_wait, fdInf, + (epfd, events, maxevents, timeout)); - NSSOC_LOGINF ("(size=%d) [Caller]", size); + nstack_fd_local_lock_info_t *local_lock = &fdInf->local_lock; + LOCK_EPOLL(epfd, fdInf, local_lock); - if (size <= 0) + 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; + + /* 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 - if (maxevents <= 0) + 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); - /** - * 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) + /* 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()); + + 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) + fork_parent_start(ppid); + pid = nsfw_base_fork(); + if (pid == 0) { - goto out; - } - else if (timeout < 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; } -- cgit 1.2.3-korg