static int mod_child(int rank) { int pid; struct ctrl_socket* cs; static int rpc_handler=0; /* do nothing from PROC_INIT, is the same as PROC_MAIN */ if (rank==PROC_INIT) return 0; /* we want to fork(), but only from one process */ if ((rank == PROC_MAIN ) && (ctrl_sock_lst)){ /* FIXME: no fork ?? */ DBG("ctl: mod_child(%d), ctrl_sock_lst=%p\n", rank, ctrl_sock_lst); /* fork, but make sure we know not to close our own sockets when * ctl child_init will be called for the new child */ rpc_handler=1; /* child should start with a correct estimated used fds number*/ register_fds(MAX_IO_READ_CONNECTIONS); pid=fork_process(PROC_RPC, "ctl handler", 1); DBG("ctl: mod_child(%d), fork_process=%d, csl=%p\n", rank, pid, ctrl_sock_lst); if (pid<0){ goto error; } if (pid == 0){ /* child */ is_main=0; DBG("ctl: %d io_listen_loop(%d, %p)\n", rank, fd_no, ctrl_sock_lst); io_listen_loop(fd_no, ctrl_sock_lst); }else{ /* parent */ /* not used in parent */ register_fds(-MAX_IO_READ_CONNECTIONS); rpc_handler=0; } } if (rank!=PROC_RPC || !rpc_handler){ /* close all the opened fds, we don't need them here */ for (cs=ctrl_sock_lst; cs; cs=cs->next){ close(cs->fd); cs->fd=-1; if (cs->write_fd!=-1){ close(cs->write_fd); cs->write_fd=-1; } } if (rank!=PROC_MAIN){ /* we need the lists in main for on_exit cleanup, see mod_destroy */ /* free memory, we don't need the lists anymore */ free_ctrl_socket_list(ctrl_sock_lst); ctrl_sock_lst=0; free_id_list(listen_lst); listen_lst=0; } } return 0; error: return -1; }
static int mod_init(void) { struct id_list* l; if (listen_lst==0) { add_binrpc_socket(PARAM_STRING, DEFAULT_CTL_SOCKET); } DBG("listening on:\n"); for (l=listen_lst; l; l=l->next){ fd_no++; switch(l->proto){ case UNIXD_SOCK: DBG(" [%s:unix dgram] %s\n", payload_proto_name(l->data_proto), l->name); break; case UNIXS_SOCK: DBG(" [%s:unix stream] %s\n", payload_proto_name(l->data_proto), l->name); break; case UDP_SOCK: DBG(" [%s:udp] %s:%d\n", payload_proto_name(l->data_proto), l->name, l->port?l->port:DEFAULT_CTL_PORT); break; case TCP_SOCK: DBG(" [%s:tcp] %s:%d\n", payload_proto_name(l->data_proto), l->name, l->port?l->port:DEFAULT_CTL_PORT); break; case FIFO_SOCK: DBG(" [%s:fifo] %s\n", payload_proto_name(l->data_proto), l->name); fd_no++; /* fifos use 2 fds */ break; default: LOG(L_CRIT, "BUG: ctrl: listen protocol %d not supported\n", l->proto); goto error; } } /* open socket now, before suid */ if (init_ctrl_sockets(&ctrl_sock_lst, listen_lst, DEFAULT_CTL_PORT, usock_mode, usock_uid, usock_gid)<0){ LOG(L_ERR, "ERROR: ctl: mod_init: init ctrl. sockets failed\n"); goto error; } if (ctrl_sock_lst){ /* we will fork */ register_procs(1); /* we will be creating an extra process */ register_fds(fd_no); /* The child process will keep updating its local configuration */ cfg_register_child(1); } #ifdef USE_FIFO fifo_rpc_init(); #endif return 0; error: return -1; }
static int mod_init(void) { struct id_list* l; char ctl_socket_path[CTL_SOCKET_PATH_SIZE]; binrpc_callbacks_init(); if(binrpc_max_body_size<=0) binrpc_max_body_size = 4; if(binrpc_struct_max_body_size<=0) binrpc_struct_max_body_size = 1; binrpc_max_body_size *= 1024; binrpc_struct_max_body_size *= 1024; if (listen_lst==0) { if(strcmp(runtime_dir, RUN_DIR)==0) { add_binrpc_socket(PARAM_STRING, DEFAULT_CTL_SOCKET); } else { if(sizeof(DEFAULT_CTL_SOCKET_PROTO) + sizeof(DEFAULT_CTL_SOCKET_NAME) + strlen(runtime_dir) + 4 > CTL_SOCKET_PATH_SIZE) { LM_ERR("ctl socket path is too big\n"); return -1; } strcpy(ctl_socket_path, DEFAULT_CTL_SOCKET_PROTO); strcat(ctl_socket_path, runtime_dir); strcat(ctl_socket_path, "/"); strcat(ctl_socket_path, DEFAULT_CTL_SOCKET_NAME); add_binrpc_socket(PARAM_STRING, ctl_socket_path); } } DBG("listening on:\n"); for (l=listen_lst; l; l=l->next){ fd_no++; switch(l->proto){ case UNIXD_SOCK: DBG(" [%s:unix dgram] %s\n", payload_proto_name(l->data_proto), l->name); break; case UNIXS_SOCK: DBG(" [%s:unix stream] %s\n", payload_proto_name(l->data_proto), l->name); break; case UDP_SOCK: DBG(" [%s:udp] %s:%d\n", payload_proto_name(l->data_proto), l->name, l->port?l->port:DEFAULT_CTL_PORT); break; case TCP_SOCK: DBG(" [%s:tcp] %s:%d\n", payload_proto_name(l->data_proto), l->name, l->port?l->port:DEFAULT_CTL_PORT); break; #ifdef USE_FIFO case FIFO_SOCK: DBG(" [%s:fifo] %s\n", payload_proto_name(l->data_proto), l->name); fd_no++; /* fifos use 2 fds */ break; #endif default: LOG(L_CRIT, "BUG: ctrl: listen protocol %d not supported\n", l->proto); goto error; } } /* get the uid/gid from core if not set for the module */ if(usock_uid==-1 && sock_uid!=-1) usock_uid = sock_uid; if(usock_gid==-1 && sock_gid!=-1) usock_gid = sock_gid; /* open socket now, before suid */ if (init_ctrl_sockets(&ctrl_sock_lst, listen_lst, DEFAULT_CTL_PORT, usock_mode, usock_uid, usock_gid)<0){ LOG(L_ERR, "ERROR: ctl: mod_init: init ctrl. sockets failed\n"); goto error; } if (ctrl_sock_lst){ /* we will fork */ register_procs(1); /* we will be creating an extra process */ register_fds(fd_no); /* The child process will keep updating its local configuration */ cfg_register_child(1); } #ifdef USE_FIFO fifo_rpc_init(); #endif return 0; error: return -1; }