/* * * Copyright (c) 2018 Huawei Technologies Co.,Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "nstack.h" #include "nstack_fd_mng.h" #include "nstack_socket.h" #include "nstack_securec.h" #include "nstack_sockops.h" /* test_epollCtl_004_001_trial : both 32bit and 64bit members of 'ops' and 'conn' need to reset, otherwise it will be invalid address in 32bit APP case */ void nstack_reset_fdInf (nstack_fd_Inf * fdInf) { int loop; fdInf->isBound = NSTACK_FD_NOBIND; fdInf->rlfd = -1; fdInf->rmidx = -1; fdInf->nxtfd = -1; fdInf->fd = -1; fdInf->attr = 0; fdInf->ops = 0; /*operations of the fd, for save space we user opIdx here */ fdInf->type = 0; /*the fd type like SOCK_STREAM|SOCK_NONBLOCK ... */ NSTACK_SET_FD_BLOCKING (fdInf); for (loop = 0; loop < NSTACK_MAX_MODULE_NUM; loop++) { fdInf->protoFD[loop].fd = -1; fdInf->protoFD[loop].errCode = 0; fdInf->protoFD[loop].pad = 0; fdInf->protoFD[loop].liststate = NSTACK_NO_LISTENING; } nstack_reset_fd_local_lock_info (&(fdInf->local_lock)); return; } nstack_fd_Inf * nstack_fd2inf (int fd) { /*if nstack init not finished, just return null */ if (NSTACK_MODULE_SUCCESS != g_nStackInfo.fwInited) { return NULL; } if (nstack_is_nstack_sk (fd) && g_nStackInfo.lk_sockPoll) { return &(g_nStackInfo.lk_sockPoll[fd]); } return NULL; } void nstack_set_protoFd (nstack_fd_Inf * fdInf, int modInx, int protofd) { if (protofd < nstack_get_minfd_id (modInx) || protofd > nstack_get_maxfd_id (modInx)) { NSSOC_LOGERR ("module:%d protofd invalid] protofd=%d", modInx, protofd); return; } nstack_get_protoFd (fdInf, modInx) = protofd; nsep_set_infoProtoFD (fdInf->fd, modInx, protofd); nssct_create (fdInf->fd, protofd, modInx); return; } /* pass app info to struct netconn */ void nstack_set_app_info (nstack_fd_Inf * fdInf, int modInx) { return; } nstack_fd_Inf * nstack_lk_fd_alloc_with_kernel (int nfd) { nstack_fd_Inf *retInf = NULL; if ((nfd < 0) || (nfd >= (int) NSTACK_KERNEL_FD_MAX) || (!g_nStackInfo.lk_sockPoll)) { NSSOC_LOGERR ("nfd < 0 or nfd>= NSTACK_KERNEL_FD_MAX, parameter not valid"); return NULL; } retInf = &g_nStackInfo.lk_sockPoll[nfd]; if (FD_OPEN == retInf->local_lock.fd_status) { NSSOC_LOGERR ("nstack_lk_fd_alloc_with_kernel fd:%d already create", nfd); } retInf->fd = nfd; if (-1 == nsep_alloc_infoWithSock (nfd)) { NSSOC_LOGERR ("Can't alloc epInfo for nfd=%d]", nfd); nstack_reset_fdInf (retInf); return NULL; } nstack_set_protoFd (retInf, g_nstack_modules.fix_mid, nfd); NSSOC_LOGDBG ("nfd=%d,retInf_fd=%d", nfd, retInf->fd); return retInf; } int nstack_fd_free_with_kernel (nstack_fd_Inf * fdInf) { int closeRet = 0; ns_int32 fd; if (!fdInf) { NSSOC_LOGERR ("fdInf is NULL"); return 0; } fd = fdInf->protoFD[nstack_get_fix_mid ()].fd; nstack_reset_fdInf (fdInf); if (fd >= 0 && fd < (int) NSTACK_KERNEL_FD_MAX) { NSTACK_CAL_FUN (nstack_fix_mid_ops (), close, (fd), closeRet); NSSOC_LOGINF ("close]fd=%d,ret=%d", fd, closeRet); } return closeRet; } void nstack_fork_init_parent (pid_t ppid) { int fd; nstack_fd_Inf *fdInf = NULL; for (fd = 0; fd < (int) NSTACK_KERNEL_FD_MAX; fd++) { fdInf = nstack_getValidInf (fd); if ((NULL != fdInf) && (!((u32_t) (fdInf->type) & SOCK_CLOEXEC))) { int i; nstack_each_modInx (i) { if ((nstack_extern_deal (i).fork_parent_fd) && (fdInf->protoFD[i].fd >= 0)) { nstack_extern_deal (i).fork_parent_fd (fdInf->protoFD[i].fd, ppid); } } } } } void nstack_fork_init_child (pid_t ppid) { pid_t cpid = updata_sys_pid (); NSSOC_LOGDBG ("parent_pid=%d, child_pid=%d", ppid, cpid); nsfw_mgr_clr_fd_lock (); if (FALSE == nsfw_recycle_fork_init ()) { NSFW_LOGERR ("init rec zone failed!]ppid=%d,cpid=%d", ppid, cpid); } int i; nstack_each_modInx (i) { if (nstack_extern_deal (i).fork_init_child) { nstack_extern_deal (i).fork_init_child (ppid, cpid); } } int pos; nstack_fd_Inf *fdInf = NULL; for (pos = 0; pos < (int) NSTACK_KERNEL_FD_MAX; pos++) { fdInf = nstack_getValidInf (pos); if (fdInf) { if (!((u32_t) (fdInf->type) & SOCK_CLOEXEC)) { nstack_fork_fd_local_lock_info (&fdInf->local_lock); nstack_each_modInx (i) { if ((nstack_extern_deal (i).fork_child_fd) && (fdInf->protoFD[i].fd >= 0)) { nstack_extern_deal (i).fork_child_fd (fdInf-> protoFD[i].fd, ppid, cpid); } } } else { nstack_reset_fd_local_lock_info (&fdInf->local_lock); nsep_set_infoSockMap (pos, NULL); nstack_each_modInx (i) { if ((nstack_extern_deal (i).fork_free_fd) && (fdInf->protoFD[i].fd >= 0)) { nstack_extern_deal (i).fork_free_fd (fdInf->protoFD[i].fd, ppid, cpid); } } } } } }