diff options
Diffstat (limited to 'video_in_hal/otherservice/rpc_library/library/src/rpc_thread.c')
-rwxr-xr-x | video_in_hal/otherservice/rpc_library/library/src/rpc_thread.c | 1224 |
1 files changed, 0 insertions, 1224 deletions
diff --git a/video_in_hal/otherservice/rpc_library/library/src/rpc_thread.c b/video_in_hal/otherservice/rpc_library/library/src/rpc_thread.c deleted file mode 100755 index df0f746..0000000 --- a/video_in_hal/otherservice/rpc_library/library/src/rpc_thread.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* - * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. - * - * 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. - */ - -/** - * @file rpc_thread.c - * @brief RPC Library Internal Implementation--Processing of Internally Generated Threads - * - */ -/** @addtogroup RPClib_in */ -/** @{ */ - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <malloc.h> -#include <fcntl.h> -#include <sys/time.h> -#include <sys/select.h> -#include <sys/poll.h> -#include <sys/prctl.h> - -#include <sys/socket.h> -#include <sys/un.h> - -#include <sys/inotify.h> - -#include <other_service/rpc.h> -#include "rpc_internal.h" - -#include <native_service/cl_monitor.h> -#include <native_service/cl_process.h> - -/** Sub-threads that wake up in the RPC library */ -static RpcThreadInfo *Thread_info[RPC_MAX_THREADS_IN_PROCESS]; -static int Num_thread_info; -pthread_t g_rpc_thread = RPC_NO_THREAD; -UINT32 g_rpc_thread_alive;/**< Sub-thread running */ - -#define RPC_MAGIC_ID (('R'<<24)|('P'<<16)|('C'<<8)|'L') - -/** Pipes used for communication with sub-threads - * Read: Main thread, Write: Sub-thread */ -int g_rpc_pipe_main_sub[2] = { -1, -1 }; - -static pthread_mutex_t process_global_mutex = PTHREAD_MUTEX_INITIALIZER; -#define PROCESS_MUTEX_LOCK rpc_mutex_lock(&process_global_mutex) -#define PROCESS_MUTEX_UNLOCK rpc_mutex_unlock(&process_global_mutex) - -static void *RpcThreadMain(void *ptr); -static void NotifyMainThread(RpcThreadInfo *th); - -static void KillRpcThread(void); -static void NotifyAddServer(RpcThreadInfo *th); -static void NotifyRemoveServer(RpcThreadInfo *th); - -static RPC_Result RpcRegistSockName(RpcIdInfo *idinfo, char *client_sock_name, const struct ucred *cr, int wd); -static RPC_Result RpcCheckSockName(RpcIdInfo *idinfo, RPC_ID client_id); -static RPC_Result RpcDeleteSockName(RpcIdInfo *idinfo, int wd); -static RPC_Result RpcAllDeleteSockName(RpcIdInfo *idinfo, int inotify_fd); -static RPC_Result RpcCheckClientCredential(RpcIdInfo *idinfo, const struct ucred *cr); - -#define RPC_SUB_THREAD_WAIT_SEC 5 - -#define WAIT_FOR_SUB_THREAD(loop_cond, sec) \ -{ \ - struct timeval timeout; \ - timeout.tv_sec = sec; \ - timeout.tv_usec = 0; \ - \ - int fd = RPC_pipe_sub_main(th)[PIPE_READ]; \ - fd_set fds; \ - \ - while((loop_cond)) { \ - FD_ZERO(&fds); \ - FD_SET(fd, &fds); \ - int sret = select(fd + 1, &fds, NULL, NULL, &timeout); \ - if (sret < 0 && errno == EINTR) { \ - continue; \ - } else if (sret > 0 && FD_ISSET(fd, &fds)) { \ - char c; \ - read(fd, &c, sizeof(c)); \ - } else { \ - break; \ - } \ - } \ -} - -RUNS_IN_CALLERS_THREAD - RpcThreadInfo * -RpcMyThreadInfo(void) { - RpcThreadInfo *ret = NULL; - int i; - pthread_t me = pthread_self(); - - PROCESS_MUTEX_LOCK; - for(i = 0; i < RPC_MAX_THREADS_IN_PROCESS ; i++) { - if (Thread_info[i] != NULL - && pthread_equal(Thread_info[i]->thread, me)) { - ret = Thread_info[i]; - break; - } - } - PROCESS_MUTEX_UNLOCK; - return ret; -} - -RUNS_IN_CALLERS_THREAD - RpcThreadInfo * -RpcCreateThreadInfo(void) { - int i; - pthread_t me = pthread_self(); - - PROCESS_MUTEX_LOCK; - /* Look for a free slot to store the thread info pointer */ - for(i = 0; i < RPC_MAX_THREADS_IN_PROCESS ; i++) { - if (Thread_info[i] != NULL) { - if (pthread_equal(Thread_info[i]->thread, me)) { // LCOV_EXCL_BR_LINE 6: double check - PROCESS_MUTEX_UNLOCK; // LCOV_EXCL_START 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return Thread_info[i]; - } // LCOV_EXCL_STOP - } else { - break; - } - } - - if (i == RPC_MAX_THREADS_IN_PROCESS) { - PROCESS_MUTEX_UNLOCK; - //CONFIG_ASSERT("Must increase RPC_MAX_THREADS_IN_PROCESS"); - RPC_LOG_ERR("Must increase RPC_MAX_THREADS_IN_PROCESS"); - return NULL; - } - - /* Allocate area for thread info */ - // Because there is a timing when the server sub-thread is accessed without being initialized, - // corrected so as to fill up to 0 in the MUTEX. - RpcThreadInfo *th = rpc_malloc(sizeof(*th)); - if (th != NULL) { // LCOV_EXCL_BR_LINE 5: fail safe for libc malloc - memset(th, 0, sizeof(*th)); - Thread_info[i] = th; - th->magic = RPC_MAGIC_ID; - Num_thread_info++; - } - PROCESS_MUTEX_UNLOCK; - - if (th == NULL) { // LCOV_EXCL_START 5: fail safe for libc malloc - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_ERR("Can't alloc thread_info."); - return NULL; - } // LCOV_EXCL_STOP - - /* Initializing Thread Info */ - th->thread = me; - pthread_mutex_init(&(th->th_mtx), NULL); - th->sequence_number = RPC_SEQ_NUM_START; - - return th; -} - -/* - * check if the allocated client ID conflicts with the server ID - * of the same thread - */ - static int -RpcCheckIdConflict(RpcThreadInfo *th, RPC_ID id) { - RpcIdInfo *idinfo; - idinfo = RPC_srvr_idinfo(th); - if (idinfo != NULL && RPC_my_id(idinfo) == id) { // LCOV_EXCL_START 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return 1; - } // LCOV_EXCL_STOP - return 0; -} - -/** Adding IDs with RPC_start() - * - * - Main: Create and initialize structures and tell sub-threads to add - * - Sub: Add pointer to thread info (RpcThreadInfo) and notify it to the main process - * - The main process waits for this procedure to finish. - * Use id_info->thread_info to determine completion (completed if not NULL) - */ -RUNS_IN_CALLERS_THREAD - int -RpcCreateIdInfo(RpcThreadInfo *th, - RPC_ID id, RPC_dispatch_func_t dispatch, INT32 secure_check) { - RpcIdInfo *id_info = rpc_malloc(sizeof(*id_info)); - if (id_info == NULL) { // LCOV_EXCL_START 5: fail safe for libc malloc - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return -1; - } // LCOV_EXCL_STOP - memset(id_info, 0, sizeof(*id_info)); - - /* - * Creates a Unix domain socket based on a given number of ports - */ -#if defined(RPC_USE_UNIX_AUTOBIND) - int sock_un = -1, secure_sock_un = -1; - socklen_t sa_len; - struct sockaddr_un sa_un; - -get_id_retry: - sock_un = socket(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); /* Datagram socket for receiving API requests */ - if (sock_un < 0) { - RPC_LOG_PERROR("socket"); - goto error; - } - SET_NONBLOCK(sock_un); - SET_CLOSE_ON_EXEC(sock_un); - - /* - * Naming Rules for Unix domain Sockets - * Server:(ID=50000-59999) - * sa_un.sun_path[0] = 0x00; - * sa_un.sun_path[1] = 'S'; - * sa_un.sun_path[2-5] = sprintf("%04x", ID); - * - * Client:(ID=1-0xfffff) - * sa_un.sun_path[0] = 0x00; - * sa_un.sun_path[1-5] = sprintf("%05x", ID); - * ID is autobind by kernel during bind(see linux/net/unix/af_unix.c) - * ! Since it depends on the unix socket implementations of Linux, be careful when porting to other operating systems. - * - * ID=50000-59999 is duplicated in Server and Client, - * but generated it according to the above rules when sent in the RPClib (see rpc_udp.c) - * - * Because file deletion is leaked when the system is forcibly terminated and abnormal process termination - * by a traditional way to create and bind files under /tmp/RPC/, - * change to the above method(2009.02.04,2012.01.21) - */ - memset(&sa_un, 0, sizeof(sa_un)); - sa_un.sun_family = AF_UNIX; - if (dispatch != NULL) { // server - RpcSetServerName(sa_un.sun_path, id); - sa_len = sizeof(sa_un.sun_family) + SOCK_NAME_LEN; - } else { // client - // Automatically assign name (ID) by unix_autobind() - sa_len = sizeof(sa_un.sun_family); - } - -#else /* !AUTOBIND */ - int sock_un = -1; - struct sockaddr_un sa_un; - sa_un.sun_family = AF_UNIX; - rpc_set_socket_name(sa_un.sun_path, id); - sock_un = socket(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); - if (sock_un < 0) { - RPC_LOG_PERROR("socket(unix)"); - goto error; - } - SET_NONBLOCK(sock_un); - SET_CLOSE_ON_EXEC(sock_un); - unlink(sa_un.sun_path); - sa_len = sizeof(sa_un); -#endif /* !AUTOBIND */ - if (bind(sock_un, (struct sockaddr *)&sa_un, sa_len) < 0) { - RPC_LOG_PERROR("DGRAM : bind(unix), ID:%#x", id); - goto error; - } - -#if defined(RPC_USE_UNIX_AUTOBIND) - if (dispatch == NULL) { // client - // Retrieves the assigned name (ID) - socklen_t len = sizeof(sa_un); - if (getsockname(sock_un, (struct sockaddr *)&sa_un, &len) < 0) { - perror("getsockname"); - goto error; - } - RpcGetClientName(sa_un.sun_path, &id); - if (RpcCheckIdConflict(th, id)) { // LCOV_EXCL_BR_LINE 8: dead code, RpcCheckIdConflict always is false - // LCOV_EXCL_START 8: dead code, RpcCheckIdConflict always is false - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_STATE("ID %d conflicts with server -- get next one", id); - close(sock_un); - goto get_id_retry; - } // LCOV_EXCL_STOP - RPC_LOG_DEBUG("client %s", sa_un.sun_path + 1); - } -#endif /* AUTOBIND */ - - id_info->port = id; - id_info->sock = sock_un; - - if (dispatch != NULL) { /* server */ - rpc_assert(th->srvr_id == NULL); // LCOV_EXCL_BR_LINE 6: double check - RpcApicallInfo *apicall = rpc_malloc(sizeof(*apicall)); - if (apicall == NULL) { // LCOV_EXCL_START 5: fail safe for libc malloc - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - goto error; - } // LCOV_EXCL_STOP - - /* Create Socket for Authentication */ - socklen_t secure_sa_len; - struct sockaddr_un secure_sa_un; - - secure_sock_un = socket(PF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); /* stream socket for authentication */ - if (secure_sock_un < 0) { - RPC_LOG_PERROR("socket"); - rpc_free(apicall); - apicall = NULL; - goto error; - } - SET_NONBLOCK(secure_sock_un); - SET_CLOSE_ON_EXEC(secure_sock_un); - - memset(&secure_sa_un, 0, sizeof(secure_sa_un)); - secure_sa_un.sun_family = AF_UNIX; - RpcSetServerSecureName(secure_sa_un.sun_path, id); - secure_sa_len = sizeof(secure_sa_un.sun_family) + SECURE_SOCK_NAME_LEN; - - /* Bind socket for authentication */ - if (bind(secure_sock_un, (struct sockaddr *)&secure_sa_un, secure_sa_len) < 0) { - RPC_LOG_PERROR("STREAM : bind(unix), ID:%#x", id); - rpc_free(apicall); - apicall = NULL; - goto error; - } - - id_info->secure_sock = secure_sock_un; - - memset(apicall, 0, sizeof(*apicall)); - apicall->dispatch_func = dispatch; - apicall->pipe_sub_main[PIPE_READ] = -1; - apicall->pipe_sub_main[PIPE_WRITE] = -1; - apicall->timeout_sec = 30; /* Server API processing timeout */ - apicall->secure_check = secure_check; /* Authentication check by UID list */ - if (NEED_SECURE_CHECK == secure_check) { /* Initializes the UID list with not-registered if secured given. */ - apicall->regist_credential_info = NO_REGISTERED; - } - apicall->sock_info_head = NULL; /* Leading Node of Source Client Socket Info */ - apicall->client_sock_name_num = 0; /* Number of elements in the source client's socket name list */ - apicall->in_process_client = RPC_NO_PORT; /* Client RPC_ID during API processing */ - - id_info->apicall = apicall; - th->srvr_id = id_info; - - /* Creating a pipe for communication pipe from sub-thread to main-thread direction */ - if (pipe(apicall->pipe_sub_main) != 0) { - RPC_LOG_PERROR("pipe"); - goto error; - } - SET_NONBLOCK(apicall->pipe_sub_main[PIPE_READ]); - SET_CLOSE_ON_EXEC(apicall->pipe_sub_main[PIPE_READ]); - SET_NONBLOCK(apicall->pipe_sub_main[PIPE_WRITE]); - SET_CLOSE_ON_EXEC(apicall->pipe_sub_main[PIPE_WRITE]); - - PROCESS_MUTEX_LOCK; - if (g_rpc_thread == RPC_NO_THREAD) { /* There are no sub-threads. */ - /* Creating a pipe for communication from main-thread to sub-thread direction */ - if (pipe(g_rpc_pipe_main_sub) != 0) { - RPC_LOG_PERROR("pipe"); - PROCESS_MUTEX_UNLOCK; - goto error; - } - - SET_NONBLOCK(g_rpc_pipe_main_sub[PIPE_READ]); - SET_CLOSE_ON_EXEC(g_rpc_pipe_main_sub[PIPE_READ]); - SET_NONBLOCK(g_rpc_pipe_main_sub[PIPE_WRITE]); - SET_CLOSE_ON_EXEC(g_rpc_pipe_main_sub[PIPE_WRITE]); - - /* Creating sub-thread */ - pthread_t read_th; - if (pthread_create(&read_th, NULL, RpcThreadMain, 0) != 0) { - RPC_LOG_PERROR("pthread_create"); - PROCESS_MUTEX_UNLOCK; - goto error; - } - g_rpc_thread = read_th; - } - PROCESS_MUTEX_UNLOCK; - - /* Instruct a sub-thread to add and wait for completion */ - NotifyAddServer(th); - // LCOV_EXCL_BR_START 15: macro define in rpc_thread.c - WAIT_FOR_SUB_THREAD((th->srvr_id->thread_info == NULL), - RPC_SUB_THREAD_WAIT_SEC); - // LCOV_EXCL_BR_STOP - rpc_assert(th->srvr_id->thread_info != NULL); // LCOV_EXCL_BR_LINE 6: double check - - } else { /* dispatch == NULL => client */ - id_info->count = 1; - id_info->thread_info = th; - th->clnt_id = id_info; - } - return 0; /* pgr0524 */ - -error: - if (g_rpc_pipe_main_sub[PIPE_READ] >= 0) { // LCOV_EXCL_BR_LINE 5: fail safe for libc socket - close(g_rpc_pipe_main_sub[PIPE_READ]); - } - if (g_rpc_pipe_main_sub[PIPE_WRITE] >= 0) { // LCOV_EXCL_BR_LINE 5: fail safe for libc socket - close(g_rpc_pipe_main_sub[PIPE_WRITE]); - } - if (id_info->apicall != NULL) { - if (id_info->apicall->pipe_sub_main[PIPE_READ] >= 0) { - close(id_info->apicall->pipe_sub_main[PIPE_READ]); - } - if (id_info->apicall->pipe_sub_main[PIPE_WRITE] >= 0) { - close(id_info->apicall->pipe_sub_main[PIPE_WRITE]); - } - rpc_free(id_info->apicall); - } - if (sock_un != -1) { - close(sock_un); -#if !defined(RPC_USE_UNIX_AUTOBIND) - unlink(sa_un.sun_path); -#endif /* !AUTOBIND */ - } - if (secure_sock_un != -1) { - close(secure_sock_un); -#if !defined(RPC_USE_UNIX_AUTOBIND) - unlink(secure_sa_un.sun_path); -#endif /* !AUTOBIND */ - } - rpc_free(id_info); - th->srvr_id = NULL; - return -1; /* pgr0524 */ -} - -/* - * Notify an unfinished request of an error at server termination (RPC_end). - */ - static void -RpcSendErrorToPendingRequest(RpcThreadInfo *th, RpcIdInfo *idinfo) { - UINT16 api_num; - RPC_ID client; - char *args_string; - unsigned int args_size; - rpc_send_buf sendbuf; - char retcode[10]; - - do { - api_num = RpcGetAPIRequest(idinfo, &client, - &args_string, &args_size); - if (api_num > 0) { /* API calls are queued */ - - sprintf(retcode, "%08x ", RPC_ERR_Fatal); - sendbuf.buf = retcode; - sendbuf.bytes = sizeof(retcode) - 1; - RpcSendUdp2(idinfo, client, RPC_SEND_TO_CLIENT, - RPC_PACKET_APIRETURN, 1, &sendbuf); - RPC_LOG_STATE("sent error result to pending client %05x", client); - RpcFreeAPIArgsString(args_string); - } - } while(api_num > 0); -} - -/* - * Notify unfinished request of deadlock when deadlock of the server is detected. - */ - static void -RpcSendDeadlockToPendingRequest(RpcThreadInfo *th, RpcIdInfo *idinfo) { - UINT16 api_num; - RPC_ID client; - char *args_string; - unsigned int args_size; - rpc_send_buf sendbuf; - char retcode[10]; - - do { - api_num = RpcGetAPIRequest(idinfo, &client, - &args_string, &args_size); - if (api_num > 0) { /* API calls are queued */ - - sprintf(retcode, "%08x ", RPC_ERR_Server_DeadLock); - sendbuf.buf = retcode; - sendbuf.bytes = sizeof(retcode) - 1; - RpcSendUdp2(idinfo, client, RPC_SEND_TO_CLIENT, - RPC_PACKET_APIRETURN, 1, &sendbuf); - RPC_LOG_STATE("sent deadlock result to pending client %05x", client); - RpcFreeAPIArgsString(args_string); - } - } while(api_num > 0); - - if (RPC_NO_PORT != RPC_apicall_in_process_client(idinfo)) { - sprintf(retcode, "%08x ", RPC_ERR_Server_DeadLock); - sendbuf.buf = retcode; - sendbuf.bytes = sizeof(retcode) - 1; - RpcSendUdp2(idinfo, RPC_apicall_in_process_client(idinfo), RPC_SEND_TO_CLIENT, - RPC_PACKET_APIRETURN, 1, &sendbuf); - RPC_LOG_STATE("sent deadlock result to pending client %05x", RPC_apicall_in_process_client(idinfo)); - RPC_apicall_in_process_client(idinfo) = RPC_NO_PORT; - } -} - -/** Delete RPC_ID Info by RPC_end() - * - * - Main: Notify sub of deletion of RPC_ID info. - * - Sub: Delete a pointer from thread info (RpcThreadInfo) and notify main of that. - * - Main waits for this procedure to finish. - * Use id_info->thread_info to determine completion (completed if NULL). - * Then, release the memory related to RPC_ID info and close the socket. - */ -RUNS_IN_CALLERS_THREAD - void -RpcDestroyIdInfo(RpcThreadInfo *th, RpcIdInfo *id_info) { - rpc_assert(id_info->count == 0); // LCOV_EXCL_BR_LINE 6: double check - if (id_info->apicall) { - if (g_rpc_thread_alive != 0) { - NotifyRemoveServer(th); - /* Wait for a sub-thread to recognize IDinfo deletion */ - // LCOV_EXCL_BR_LINE 15: macro define in rpc_thread.c - WAIT_FOR_SUB_THREAD((th->srvr_id->thread_info != NULL), - RPC_SUB_THREAD_WAIT_SEC); - // LCOV_EXCL_BR_STOP - rpc_assert(th->srvr_id->thread_info == NULL); /* not recognized yet */ // LCOV_EXCL_BR_LINE 6: double check - } - - if (id_info->apicall->pipe_sub_main[PIPE_READ] >= 0) { - close(id_info->apicall->pipe_sub_main[PIPE_READ]); - } - if (id_info->apicall->pipe_sub_main[PIPE_WRITE] >= 0) { - close(id_info->apicall->pipe_sub_main[PIPE_WRITE]); - } - if (id_info->secure_sock >= 0) { - close(id_info->secure_sock); - } - rpc_free(id_info->apicall); - th->srvr_id = NULL; - } else { - th->clnt_id = NULL; - } - rpc_free(id_info); -} - -RUNS_IN_CALLERS_THREAD - void -RpcDestroyThreadInfo(void) { - unsigned int i; - RpcThreadInfo *th = RpcMyThreadInfo(); - if (th == NULL) { - return; - } - - RPC_THREAD_MUTEX_LOCK(th); - if (th->thread == RPC_NO_THREAD) { // LCOV_EXCL_BR_LINE 6: double check - RPC_THREAD_MUTEX_UNLOCK(th); // LCOV_EXCL_START 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return; - } // LCOV_EXCL_STOP - th->thread = RPC_NO_THREAD; - RPC_THREAD_MUTEX_UNLOCK(th); - - PROCESS_MUTEX_LOCK; - /* - * Remove the pointer from the global variable. - * Subsequent calls to RpcMyThreadInfo() return NULL - */ - for(i = 0; i < RPC_MAX_THREADS_IN_PROCESS ; i++) { - if (th == Thread_info[i]) { - Thread_info[i] = NULL; - Num_thread_info--; - break; - } - } - PROCESS_MUTEX_UNLOCK; - BUG_ASSERT(i < RPC_MAX_THREADS_IN_PROCESS, "No info in Thread_info[]"); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_internal.h - - if (Num_thread_info == 0 && g_rpc_thread_alive != 0) { - KillRpcThread(); - char name[32]; - prctl(PR_GET_NAME, name); - RPC_LOG_DEBUG("[%s]waiting for sub thread to join...", name); - pthread_join(g_rpc_thread, NULL); - RPC_LOG_DEBUG("[%s]sub thread joined.", name); - g_rpc_thread = RPC_NO_THREAD; /* bug fix */ - rpc_assert(g_rpc_thread_alive == 0); // LCOV_EXCL_BR_LINE 6: double check - close(g_rpc_pipe_main_sub[PIPE_READ]); - close(g_rpc_pipe_main_sub[PIPE_WRITE]); - } - - if (th->srvr_id != NULL) { // LCOV_EXCL_BR_LINE 6: double check - RpcDestroyIdInfo(th, th->srvr_id); // LCOV_EXCL_START 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - th->srvr_id = NULL; - } // LCOV_EXCL_STOP - if (th->clnt_id != NULL) { // LCOV_EXCL_BR_LINE 6: double check - RpcDestroyIdInfo(th, th->clnt_id); // LCOV_EXCL_START 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - th->clnt_id = NULL; - } // LCOV_EXCL_STOP - - pthread_mutex_destroy(&(th->th_mtx)); - rpc_free(th); -} - -#if !defined(RPC_USE_UNIX_AUTOBIND) -/** - * Sub-function of RPC_end_all() - * - * Assuming releasing memory and closing the socket are processing at immediately after the end of the process, - * Suppress socket file leaks by only deleting socket files because to avoid deadlocks and shorten the time - * by exclusive processing. - */ - void -RpcUnlinkSocketFiles(void) { - int i; - char sock_name[16]; - - for(i = 0; i < RPC_MAX_THREADS_IN_PROCESS ; i++) { - RpcThreadInfo *th = Thread_info[i]; - if (th != NULL) { - if (th->srvr_id != NULL) { - rpc_set_socket_name(sock_name, RPC_port(th->srvr_id)); - RPC_LOG_STATE("unlink srvr %s", sock_name); - unlink(sock_name); - } - if (th->clnt_id != NULL) { - rpc_set_socket_name(sock_name, RPC_port(th->clnt_id)); - RPC_LOG_STATE("unlink clnt %s", sock_name); - unlink(sock_name); - } - } - } -} -#endif /* !AUTOBIND */ - -/* - * Deadlock detection check for servers in the thread - */ - static void -RpcDeadlockCheck(RpcThreadInfo** thread_info, unsigned int num_thread_info) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - - unsigned int i = 0; - for(i = 0 ; i < num_thread_info ; i++) { - RpcThreadInfo *th = thread_info[i]; - RpcIdInfo *idinfo = th->srvr_id; - CL_MonitorEntry_t entry; - - if (0 == CL_MonitorGetEntry(CL_MONITOR_TYPE_RPC, RPC_port(idinfo), &entry)) { - if (entry.state == CL_MONITOR_STATE_RUN && entry.timeout <= ts.tv_sec) { - RPC_LOG_ERR("Time Out : RPC_ID = %#x API_NUM = %#x", entry.id, entry.user_data); - fprintf(stderr, "Time Out : RPC_ID = %#x API_NUM = %#x\n", entry.id, entry.user_data); - RpcSendDeadlockToPendingRequest(th, idinfo); - } - } - } -} -/** Main functions of the sub-threads (READING THREAD) -*/ -RUNS_IN_READING_THREAD - static void * -RpcThreadMain(void *ptr __attribute__((unused))) { - struct pollfd wait_files[RPC_MAX_FD_IN_PROCESS]; - RpcThreadInfo *thread_info[RPC_MAX_THREADS_IN_PROCESS]; - unsigned int num_thread_info = 0; - - unsigned int poll_num; - int need_reset_sockfd = 1; - int normal_exit = 0; - RPC_Result result; - unsigned int i, j; - - /* Monitoring for clients process with inotify() *//* Monitoring target filename */ - const int inotify_fd = inotify_init1(IN_CLOEXEC); /* fd for process monitoring with inotify() */ - - UINT8 readbuf[RPC_UDP_PACKET_SIZE]; - memset(readbuf, 0, sizeof(UINT8) * RPC_UDP_PACKET_SIZE); - - g_rpc_thread_alive = 1; - - CL_MonitorInit(CL_MONITOR_INIT_USER); /* Using the API for Error Monitoring */ - - // Name the thread created in the RPClib (append "_R") -#define RPC_APPEND_NAME "_R" -#ifndef PRF_SIZE_PROCESSNAME -#define PRF_SIZE_PROCESSNAME 8 /* Limit name length for Profiler Analysis Tools */ -#endif - { - char *p, name[32]; - prctl(PR_GET_NAME, name); - name[PRF_SIZE_PROCESSNAME] = '\0'; - if (strlen(name) + strlen(RPC_APPEND_NAME) > PRF_SIZE_PROCESSNAME) { - p = name + PRF_SIZE_PROCESSNAME - strlen(RPC_APPEND_NAME); - } else { - p = name + strlen(name); - } - strcpy(p, RPC_APPEND_NAME); - prctl(PR_SET_NAME, name); - } - - /* Set the communication pipe with the main thread to poll fd */ - poll_num = 1; - wait_files[0].fd = g_rpc_pipe_main_sub[PIPE_READ]; - wait_files[0].events = POLLIN; - -restart: - for( ; ; ) { - if (need_reset_sockfd) { - /* Set the UDP socket of each RPC_ID to poll fd */ - PROCESS_MUTEX_LOCK; - for(i = 0, j = 0 ; i < RPC_MAX_THREADS_IN_PROCESS ; i++) { - if (Thread_info[i] != NULL) { - if (Thread_info[i]->magic != RPC_MAGIC_ID) { // LCOV_EXCL_BR_LINE 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_ERR("Someone(me?) destroyed my area!"); // LCOV_EXCL_LINE 6: double check - } - if (Thread_info[i]->srvr_id != NULL - && Thread_info[i]->srvr_id->thread_info != NULL) { - thread_info[j] = Thread_info[i]; - j++; - } - } - } - PROCESS_MUTEX_UNLOCK; - num_thread_info = j; - - poll_num = 1; - /* Register fd for monitoring with inotify() in poll() */ - wait_files[1].fd = inotify_fd; - wait_files[1].events = POLLIN; - - poll_num = 2; - for(i = 0 ; i < num_thread_info ; i++) { - /* Datagram socket for API request */ - wait_files[poll_num].fd = thread_info[i]->srvr_id->sock; /* pgr0000 */ - wait_files[poll_num].events = POLLIN; - poll_num++; - // LCOV_EXCL_BR_START 5: fail safe for libc listen - /* Authentication stream socket */ - if (0 != listen(thread_info[i]->srvr_id->secure_sock, 10)) { /* Number of queues */ - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_PERROR("listen(unix)"); // LCOV_EXCL_LINE 5: fail safe for libc listen - } - // LCOV_EXCL_BR_STOP - wait_files[poll_num].fd = thread_info[i]->srvr_id->secure_sock; - wait_files[poll_num].events = POLLIN; - poll_num++; - } - need_reset_sockfd = 0; - } - - int pollret; - pollret = poll(wait_files, poll_num, TIMEOUT_FOR_DEADLOCK_CHECK); - - int save_errno = errno; - - RpcDeadlockCheck(thread_info, num_thread_info); - if (pollret < 0) { // LCOV_EXCL_BR_LINE 5: fail safe for libc poll - if (save_errno == EINTR) { // LCOV_EXCL_START 5: fail safe for libc poll - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - continue; - } else { - rpc_assert(pollret > 0); - goto exit_read_thread; - } // LCOV_EXCL_STOP - } - - /* Commands from the main thread (via pipe) */ - if ((wait_files[0].revents & POLLIN) == POLLIN) { - char buf[RPC_MAIN_SUB_COMMAND_SIZE]; - long ret, arg; - int cmd; - RpcThreadInfo *th; - ret = read(wait_files[0].fd, buf, sizeof(buf)); - if (ret == sizeof(buf)) { - sscanf(buf, RPC_MAIN_SUB_COMMANDs, &cmd, &arg); - switch(cmd) { - case RPC_COMMAND_ADD_SERVER: - th = (RpcThreadInfo *)arg; - th->srvr_id->thread_info = th; /* Indicate the completion of the processing */ - NotifyMainThread(th); - need_reset_sockfd = 1; - goto restart; - break; - - case RPC_COMMAND_REMOVE_SERVER: - th = (RpcThreadInfo *)arg; - RpcSendErrorToPendingRequest(th, th->srvr_id); - - RpcAllDeleteSockName(th->srvr_id, inotify_fd); /* delete client_sock_name_list */ - rpc_free((th->srvr_id)->apicall->uid_list); /* delete uid_list */ - rpc_free((th->srvr_id)->apicall->gid_list); /* delete gid_list */ - - th->srvr_id->thread_info = NULL;/* Indicate the completion of the processing */ - NotifyMainThread(th); - need_reset_sockfd = 1; - goto restart; - break; - - case RPC_COMMAND_EXIT: - /************ Termination request from the parent thread *************/ - RPC_LOG_DEBUG("Received exit command from main thread."); - normal_exit = 1; - goto exit_read_thread; - break; - } /* switch */ - } /* if (ret == sizeof(buf)) */ - } /* Complete the processing of commands from the main thread */ - - /* Client Monitoring Events with inotify() */ - if ((wait_files[1].revents & POLLIN) == POLLIN) { - UINT32 read_len = 0; - int length = 0; - char *buffer; - buffer = (char *)rpc_malloc(BUF_LEN); - if (NULL == buffer) {// LCOV_EXCL_START 5: fail safe for libc malloc - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_ERR("rpc_malloc() ERROR."); - goto exit_read_thread; - } // LCOV_EXCL_STOP - - if( (length = (int)read( inotify_fd, buffer, BUF_LEN ) ) < 0 ) { // LCOV_EXCL_START 5: fail safe for libc read - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_PERROR("inotify read() ERROR."); - rpc_free(buffer); - buffer = NULL; - goto exit_read_thread; - } // LCOV_EXCL_STOP - while ( read_len < length ) { - struct inotify_event *event = ( struct inotify_event * )&buffer[read_len]; - - if ( event->mask & IN_DELETE_SELF ) {/* Terminating a Client Process */ - int i; /* Looping variable */ - - /* Delete the source socket name from all RpcThreadInfo in the received thread */ - for(i = 0 ; i < num_thread_info ; i++) { - RpcThreadInfo *th = thread_info[i]; - RpcDeleteSockName(th->srvr_id, event->wd); - } - } - read_len += (UINT32)(EVENT_SIZE + event->len); /* Size of the inotify_event structure */ - } - rpc_free(buffer); - goto restart; - } /* Client Monitoring Events Completed with inotify() */ - - for(i = 2 ; i < poll_num ; i++) { - /* Event to the API request datagram socket */ - if ((i % 2 == 0) && ((wait_files[i].revents & POLLIN) == POLLIN)) { - unsigned int thread_info_num = ((i/2) - 1); /* Compute thread_info[thread_info_num] with events */ - RpcThreadInfo *th = thread_info[thread_info_num]; /* pgr0000 */ - RpcIdInfo *idinfo = th->srvr_id; - for(;;) { - /* RPClib packet received */ - int readret = RpcReadUdpPacket(idinfo, readbuf); - if (readret < 0) { // LCOV_EXCL_BR_LINE 5: fail safe for libc recvfrom - rpc_assert(readret >= 0); // LCOV_EXCL_START 5: fail safe for libc recvfrom - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - goto exit_read_thread; - // LCOV_EXCL_STOP - } else if (readret == 0) { - break; - } - /* successfully read udp packets */ - /* parse the packet and queue events */ - RPC_ID sender = RPC_NO_ID; - UINT32 seq_num = 0; - UINT32 size = 0; - RPC_packet_type command = RPC_PACKET_NONE; - if (RpcParsePacketHeader((const char *)readbuf, &command, &sender, &seq_num, &size) != RPC_OK) { // LCOV_EXCL_BR_LINE 11: Unexpected branch // NOLINT(readability/nolint) - goto exit_read_thread; - } - - long int api_num; - char *buff; - - switch(command) { - case RPC_PACKET_APICALL: - if (RPC_DEBUG != NULL) { // LCOV_EXCL_BR_LINE 7: debug - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - printf("RPC[%s]: received APIcall\n", RPC_DEBUG); // LCOV_EXCL_LINE 7: debug - } - // Return response without queuing for ALIVE query - api_num = strtol((const char *)(readbuf + RPC_PACKET_HEADER_LEN), NULL, 10); - if (api_num == RPC_API_NUM_RPC_ALIVE) { - RpcSendUdpResponse(idinfo, sender, RPC_SEND_TO_CLIENT, - RPC_RESPONSE_APICALL, - seq_num, "OK", sizeof("OK")); - break; - } - - /* Return BUSY if secure and unregistered in UID-list */ - if ((NEED_SECURE_CHECK == RPC_secure_check(idinfo)) - && (NO_REGISTERED == RPC_regist_credential_info(idinfo))) { - RpcSendUdpResponse(idinfo, sender, RPC_SEND_TO_CLIENT, - RPC_RESPONSE_APICALL, - seq_num, "BUSY", sizeof("BUSY")); - RPC_LOG_ERR("Need UID list register."); - break; - } - - result = RpcQueueAPIRequestBefore(idinfo, size, (char**)&buff); - if (result == RPC_OK) { - /* Check whether the source has been authenticated */ - if(RPC_OK == RpcCheckSockName(idinfo, sender)) { /* Registerd the name of the source socket */ - RpcSendUdpResponse(idinfo, sender, RPC_SEND_TO_CLIENT, - RPC_RESPONSE_APICALL, - seq_num, "OK", sizeof("OK")); - RpcQueueAPIRequestAfter(idinfo, sender, - (const char *)(readbuf + RPC_PACKET_HEADER_LEN), - size, buff); - } else { /* Not registered (in other words, first communication with the source client) */ - /* Authentication request to the client */ - RPC_THREAD_MUTEX_UNLOCK(idinfo->thread_info); - RpcSendUdpResponse(idinfo, sender, RPC_SEND_TO_CLIENT, - RPC_RESPONSE_APICALL, - seq_num, "CERT", sizeof("CERT")); - rpc_free(buff); - break; - } - } else if (result == RPC_ERR_Busy) { // LCOV_EXCL_BR_LINE 5: fail safe for libc malloc - RpcSendUdpResponse(idinfo, sender, RPC_SEND_TO_CLIENT, - RPC_RESPONSE_APICALL, - seq_num, "BUSY", sizeof("BUSY")); - } else { // LCOV_EXCL_START 5: fail safe for libc malloc - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RpcSendUdpResponse(idinfo, sender, RPC_SEND_TO_CLIENT, - RPC_RESPONSE_APICALL, - seq_num, "ERR", sizeof("ERR")); - RPC_LOG_ERR("queueing APIcall failed.(%d)", result); - goto exit_read_thread; - } // LCOV_EXCL_STOP - NotifyMainThread(th); - if (RPC_DEBUG != NULL) { // LCOV_EXCL_BR_LINE 7: debug - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - printf("RPC[%s]: notified APIcall\n", RPC_DEBUG); // LCOV_EXCL_LINE 7: debug - } - break; - - default: - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - BUG_ASSERT(0, "Unknown UDP packet type"); // LCOV_EXCL_LINE 15: marco defined in rpc_internal.h - goto exit_read_thread; - break; - } /* switch(command) */ - }/* for(;;) */ - - /* Event to the stream socket for authentication */ - } else if ((i % 2 != 0) && ((wait_files[i].revents & POLLIN) == POLLIN)) { - unsigned int thread_info_num = ((i-1)/2 - 1); /* Compute thread_info[thread_info_num] with events */ - struct sockaddr_un client_sa_un; - socklen_t client_len = sizeof(struct sockaddr_un); - struct ucred cr; /* Structure of client credit info */ - RpcCertifyResult send_ret; /* Authentication result to pass to the client */ - RpcThreadInfo *th = thread_info[thread_info_num]; - RpcIdInfo *idinfo = th->srvr_id; - - send_ret.certify_res = CERTIFY_NG; - send_ret.srvr_pid = 0; - - /* Obtain client credit info from a connected socket */ - int accept_sock = accept4(wait_files[i].fd, (struct sockaddr *)&client_sa_un, &client_len, SOCK_CLOEXEC); - int ret = getsockopt(accept_sock, SOL_SOCKET, SO_PEERCRED, &cr, &client_len); - if (ret == 0) { // LCOV_EXCL_BR_LINE 5: fail safe for libc getsockopt - client_sa_un = (struct sockaddr_un )client_sa_un; - /* Check if UID of client is allowed to communicate */ - if (RPC_OK == RpcCheckClientCredential(idinfo, &cr)) { - - /* Obtain the socket name associated with the RPC_ID of the client from the socket info */ - char client_sock_name[SOCK_NAME_LEN]; - RpcGetClientNameFromSock(client_sa_un.sun_path, client_sock_name); - - /* Monitoring client processes with inotify */ - char intfy_fname[32]; - snprintf(intfy_fname, sizeof(intfy_fname), CL_INTFY_FILENAME_FORMAT, cr.pid); - int wd = inotify_add_watch(inotify_fd, intfy_fname, IN_DELETE_SELF); - if (0 > wd) { // LCOV_EXCL_BR_LINE 5: fail safe for libc inotify_add_watch - RPC_LOG_STATE("intfy_fname is Not Found [%s].", intfy_fname); - } - - /* Register the source socket name in the management table */ - RpcRegistSockName(idinfo, client_sock_name, &cr, wd); - - /* Send server credit info to the client */ - send_ret.certify_res = CERTIFY_OK; - send_ret.srvr_pid = getpid(); - } - } - - /* Send authentication result to client */ - send(accept_sock, (char*)&send_ret, sizeof(RpcCertifyResult), 0); - close(accept_sock); - - goto restart; - - } else if ((wait_files[i].revents & ~POLLIN) != 0) { // LCOV_EXCL_START 5: fail safe for libc poll - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - // POLLERR, etc. on UDP port - RPC_LOG_STATE("poll error %x", wait_files[i].revents); - - if ((wait_files[i].revents & POLLNVAL) == POLLNVAL) { - need_reset_sockfd = 1; - goto restart; - } - } /* if ((wait_files[i].revents & POLLIN) == POLLIN) */ // LCOV_EXCL_STOP - - } /* processing UDP packets finished */ - - } /* end of forever loop */ - -exit_read_thread: - - g_rpc_thread_alive = 0; - for(i = 0 ; i < num_thread_info ; i++) { // LCOV_EXCL_BR_LINE 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - NotifyMainThread(thread_info[i]); /* pgr0000 */ // LCOV_EXCL_LINE 6: double check - } - - close(inotify_fd); - - if (normal_exit == 0) { // LCOV_EXCL_BR_LINE 6: double check - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - RPC_LOG_CRIT("sub thread ABNORMALLY exited."); // LCOV_EXCL_LINE 6: double check - } else { - RPC_LOG_DEBUG("sub thread normally exited."); - } - return NULL; -} - -/* Notification of sub-thread -> main-thread (via pipe) */ -RUNS_IN_READING_THREAD - static void -NotifyMainThread(RpcThreadInfo *th) { - rpc_assert(th->srvr_id->apicall != NULL); // LCOV_EXCL_BR_LINE 6: double check - char c = 0; - write(th->srvr_id->apicall->pipe_sub_main[PIPE_WRITE], &c, sizeof(c)); -} - -/* Notification of main-thread -> sub-thread(via pipe) */ -/* Termination instruction */ -RUNS_IN_CALLERS_THREAD - static void -KillRpcThread(void) { - char buf[RPC_MAIN_SUB_COMMAND_SIZE]; - sprintf(buf, RPC_MAIN_SUB_COMMAND, RPC_COMMAND_EXIT, (unsigned long)0); - write(g_rpc_pipe_main_sub[PIPE_WRITE], buf, sizeof(buf)); -} - -/* AddRPC_ID */ -RUNS_IN_CALLERS_THREAD - static void -NotifyAddServer(RpcThreadInfo *th) { - char buf[RPC_MAIN_SUB_COMMAND_SIZE]; - sprintf(buf, RPC_MAIN_SUB_COMMAND, RPC_COMMAND_ADD_SERVER, - (unsigned long)th); - write(g_rpc_pipe_main_sub[PIPE_WRITE], buf, sizeof(buf)); -} - -/* Remove RPC_ID */ -RUNS_IN_CALLERS_THREAD - static void -NotifyRemoveServer(RpcThreadInfo *th) { - char buf[RPC_MAIN_SUB_COMMAND_SIZE]; - sprintf(buf, RPC_MAIN_SUB_COMMAND, RPC_COMMAND_REMOVE_SERVER, - (unsigned long)th); - write(g_rpc_pipe_main_sub[PIPE_WRITE], buf, sizeof(buf)); -} - -/* Register the socket name of the source client in the management table. */ - static RPC_Result -RpcRegistSockName(RpcIdInfo *idinfo, char *client_sock_name, const struct ucred *cr, int wd) { - if ((NULL == idinfo) || (NULL == client_sock_name) || (NULL == cr) || (0 > cr->pid)) { // LCOV_EXCL_BR_LINE 6: void *RpcThreadMain(void *ptr) - RPC_LOG_ERR("RpcRegistSockName() : Invalid Param."); // LCOV_EXCL_START 6: void *RpcThreadMain(void *ptr) - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return RPC_ERR_Fatal; - } // LCOV_EXCL_STOP - - RpcClientSockNameInfo *sock_name_buf, *current; - - sock_name_buf = rpc_malloc(sizeof(RpcClientSockNameInfo)); - // LCOV_EXCL_BR_START 5: fail safe for libc malloc - if( sock_name_buf == NULL ){ - return RPC_ERR_Fatal; - } - // LCOV_EXCL_BR_STOP - strcpy(sock_name_buf->client_sock_name, client_sock_name); /* Socket name */ - sock_name_buf->pid = cr->pid; /* PID */ - sock_name_buf->uid = cr->uid; /* UID */ - sock_name_buf->gid = cr->gid; /* GID */ - sock_name_buf->wd = wd; /* Non-negative inotify monitored descriptors */ - sock_name_buf->next = NULL; /* Pointer to next node (NULL since last node) */ - - if (0 == RPC_client_sock_name_num(idinfo)) { - RPC_sock_info_head(idinfo) = sock_name_buf; - } else { - for (current = RPC_sock_info_head(idinfo); current->next != NULL; current = current->next) - ; - current->next = sock_name_buf; - } - RPC_client_sock_name_num_inc(idinfo); - return RPC_OK; -} - -/* Check if the socket name of the source client is registered in the management table */ - static RPC_Result -RpcCheckSockName(RpcIdInfo *idinfo, RPC_ID client_id) { - if ((NULL == idinfo) || (client_id == RPC_NO_ID)) { // LCOV_EXCL_BR_LINE 6: void *RpcThreadMain(void *ptr) - RPC_LOG_ERR("RpcCheckSockName() : Invalid Param."); // LCOV_EXCL_START 6: void *RpcThreadMain(void *ptr) - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return RPC_ERR_Fatal; - } // LCOV_EXCL_STOP - - char buf[7], client_path_name[SOCK_NAME_LEN]; /* Client socket name */ - - /* Converting client_id to the socket name associated with RPC_ID */ - RpcSetClientName(buf, client_id); - memcpy(client_path_name, buf + 1, 5); - client_path_name[5] = '\0'; - RpcClientSockNameInfo *current = RPC_sock_info_head(idinfo); - - /* Search source socket name in management table */ - while (NULL != current) { - if (0 == strcmp(current->client_sock_name, client_path_name)) { /* Registered socket name (authenticated) */ - return RPC_OK; - } - current = current->next; - } - return RPC_ERR_Fatal; /* Not registerd socket name (unauthenticated) */ -} - -/* Remove source client socket name from management table */ - static RPC_Result -RpcDeleteSockName(RpcIdInfo *idinfo, int wd) { - if ((NULL == idinfo) || (0 > wd)) { - RPC_LOG_ERR("RpcDeleteSockName() : Invalid Param."); - return RPC_ERR_Fatal; - } - - RpcClientSockNameInfo *current, *previous; - current = RPC_sock_info_head(idinfo); - previous = current; - int cnt = 0; - - /* Remove Source Socket Name in Management Table */ - while (NULL != current) { - if (wd == current->wd) { /* Delete element */ - if (0 == cnt) { /* Delete the start element in the management table */ - RPC_sock_info_head(idinfo) = RPC_sock_info_head(idinfo)->next; - rpc_free(current); - current = RPC_sock_info_head(idinfo); - cnt = -1; - } else { /* Delete other than the start element in the management table */ - previous->next = current->next; - rpc_free(current); - current = previous->next; - } - RPC_client_sock_name_num_dec(idinfo); - } else { /* Refer to the next node without deleting */ - previous = current; - current = current->next; - } - cnt ++; - } - - return RPC_OK; -} - -/* Remove all source client socket names in the management table */ - static RPC_Result -RpcAllDeleteSockName(RpcIdInfo *idinfo, int inotify_fd) { - if (NULL == idinfo) { // LCOV_EXCL_BR_LINE 6: double check in void RpcDestroyThreadInfo(void) - RPC_LOG_ERR("RpcAllDeleteSockName() : Invalid Param."); // LCOV_EXCL_START 6: void RpcDestroyThreadInfo(void) - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return RPC_ERR_Fatal; - } // LCOV_EXCL_STOP - - RpcClientSockNameInfo *current = RPC_sock_info_head(idinfo); - - while (NULL != current) { - RpcClientSockNameInfo *previous = current; - current = current->next; - - if (0 <= previous->wd) { - inotify_rm_watch(inotify_fd, previous->wd); - } - - rpc_free(previous); - previous = NULL; - RPC_client_sock_name_num_dec(idinfo); - } - - return RPC_OK; -} - - -/* Check if client is allowed to communicate */ - static RPC_Result -RpcCheckClientCredential(RpcIdInfo *idinfo, const struct ucred *cr) { - if ((NULL == idinfo) || (NULL == cr)) { // LCOV_EXCL_BR_LINE 6: double check in void *RpcThreadMain(void *ptr) - RPC_LOG_ERR("RpcCheckClientCredential() : Invalid Param."); // LCOV_EXCL_START 6: void *RpcThreadMain(void *ptr) - AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert - return RPC_ERR_Fatal; - } // LCOV_EXCL_STOP - - /* Retern RPC_OK if authentication is not required */ - if (NO_SECURE_CHECK == RPC_secure_check(idinfo)) { - return RPC_OK; - } - - INT32 i = 0; /* Loop counter */ - - /* Search client UID in registered UID list */ - for(i = 0; i < RPC_uid_num(idinfo); i++) { - if(RPC_uid_list(idinfo, i) == cr->uid) { /* Found UID in registered UID list */ - return RPC_OK; - } - } - - /* Search client GID in registered GID list */ - for(i = 0; i < RPC_gid_num(idinfo); i++) { - if(RPC_gid_list(idinfo, i) == cr->gid) { /* Found GID in registered GID list. */ - return RPC_OK; - } - } - - RPC_LOG_ERR("[Client isn't authenticated!!!!]"); - return RPC_ERR_Fatal; /* Not found UID in registered UID list */ -} |