diff --git a/cwmp.c b/cwmp.c index 7d26f39..acca85d 100644 --- a/cwmp.c +++ b/cwmp.c @@ -518,6 +518,12 @@ void *thread_exit_program (void *v) exit(EXIT_SUCCESS); } +void signal_handler(int signal_num) +{ + close(cwmp_main.cr_socket_desc); + _exit(EXIT_SUCCESS); +} + int main(int argc, char **argv) { @@ -528,6 +534,7 @@ int main(int argc, char **argv) pthread_t download_thread; pthread_t ubus_thread; pthread_t http_cr_server_thread; + struct sigaction act = {0}; if (error = cwmp_init(argc, argv, cwmp)) { @@ -548,6 +555,10 @@ int main(int argc, char **argv) http_server_init(); + act.sa_handler = signal_handler; + sigaction(SIGINT, &act, 0); + sigaction(SIGTERM, &act, 0); + error = pthread_create(&http_cr_server_thread, NULL, &thread_http_cr_server_listen, NULL); if (error<0) { diff --git a/http.c b/http.c index 3375574..b753568 100644 --- a/http.c +++ b/http.c @@ -43,7 +43,6 @@ #define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4" static struct http_client http_c; -static int cr_socket_desc; #ifdef HTTP_CURL static CURL *curl; @@ -339,34 +338,37 @@ http_done: void http_server_init(void) { - struct sockaddr_in server; - int cr_port; + struct sockaddr_in server = {0}; + unsigned short cr_port; for(;;) { - cr_port = cwmp_main.conf.connection_request_port; - int i = (DEFAULT_CONNECTION_REQUEST_PORT == cr_port)? 1 : 0; + cr_port = (unsigned short) (cwmp_main.conf.connection_request_port); + unsigned short i = (DEFAULT_CONNECTION_REQUEST_PORT == cr_port)? 1 : 0; //Create socket - cr_socket_desc = socket(AF_INET , SOCK_STREAM , 0); - if (cr_socket_desc == -1) + cwmp_main.cr_socket_desc = socket(AF_INET , SOCK_STREAM , 0); + if (cwmp_main.cr_socket_desc == -1) { CWMP_LOG (ERROR,"Could not open server socket for Connection Requests, Error no is : %d, Error description is : %s", errno, strerror(errno)); sleep(1); continue; } - /* enable SO_REUSEADDR */ + fcntl(cwmp_main.cr_socket_desc, F_SETFD, fcntl(cwmp_main.cr_socket_desc, F_GETFD) | FD_CLOEXEC); + int reusaddr = 1; - if (setsockopt(cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) { + if (setsockopt(cwmp_main.cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) + { CWMP_LOG (WARNING,"setsockopt(SO_REUSEADDR) failed"); } //Prepare the sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; + for(;;i++) { server.sin_port = htons(cr_port); //Bind - if( bind(cr_socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) + if( bind(cwmp_main.cr_socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) { //print the error message CWMP_LOG (ERROR,"Could not bind server socket on the port %d, Error no is : %d, Error description is : %s", cr_port, errno, strerror(errno)); @@ -387,7 +389,7 @@ void http_server_init(void) void http_server_listen(void) { - int client_sock , c , *new_sock; + int client_sock , c; static int cr_request = 0; static time_t restrict_start_time = 0; time_t current_time; @@ -395,11 +397,11 @@ void http_server_listen(void) struct sockaddr_in client; //Listen - listen(cr_socket_desc , 3); + listen(cwmp_main.cr_socket_desc , 3); //Accept and incoming connection c = sizeof(struct sockaddr_in); - while( (client_sock = accept(cr_socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) + while( (client_sock = accept(cwmp_main.cr_socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) { current_time = time(NULL); service_available = true; diff --git a/inc/cwmp.h b/inc/cwmp.h index 41eef8d..9b37e8b 100644 --- a/inc/cwmp.h +++ b/inc/cwmp.h @@ -187,6 +187,7 @@ typedef struct cwmp { time_t start_time; struct session_status session_status; unsigned int cwmp_id; + int cr_socket_desc; } cwmp; typedef struct session { diff --git a/init/cwmpd.init b/init/cwmpd.init index 21aff34..c3cc1ee 100644 --- a/init/cwmpd.init +++ b/init/cwmpd.init @@ -133,38 +133,33 @@ start_cwmpd() { fi } -get_process_childs() { +kill_process_childs() { local pid_list="$1" - local proc="" line="" pt="" ppid="" pid="" pid_tmp="" pid_grep="" + local proc="" line="" pt="" ppid="" pid="" pid_childs="" pid_grep="" + [ "$pid_list" = "" ] && return pid_grep=${pid_list// /\\|} - while [ "_$pid_grep" != "_" ];do - proc=`cat /proc/[0-9]*/stat | grep "$pid_grep"` - proc=${proc// /;;;;;} - pid_tmp="" - for line in $proc; do - pid="${line%%;;;;;*}" - ppid="${line#*;;;;;*;;;;;*;;;;;}"; ppid="${ppid%%;;;;;*}" - pt=`echo "$pid" | grep "$pid_grep"` - if [ "_$pt" != "_" -a "$pt" = "$pid" ]; then - continue - fi - pt=`echo "$ppid" | grep "$pid_grep"` - if [ "$pt" != "$ppid" -o "_$pid" = "_" ]; then - continue - fi - pid_list="$pid_list $pid" - if [ "_$pid_tmp" = "_" ]; then - pid_tmp="$pid" - else - pid_tmp="$pid_tmp\|$pid" - fi - done - pid_grep="$pid_tmp" + proc=`cat /proc/[0-9]*/stat | grep "$pid_grep"` + proc=${proc// /;;;;;} + for line in $proc; do + pid="${line%%;;;;;*}" + ppid="${line#*;;;;;*;;;;;*;;;;;}"; ppid="${ppid%%;;;;;*}" + pt=`echo "$pid" | grep "$pid_grep"` + if [ "_$pt" != "_" -a "$pt" = "$pid" ]; then + continue + fi + pt=`echo "$ppid" | grep "$pid_grep"` + if [ "$pt" != "$ppid" -o "_$pid" = "_" ]; then + continue + fi + pid_childs="$pid_childs $pid" done - echo "$pid_list" + pid_childs=${pid_childs% } + pid_childs=${pid_childs# } + kill_process_childs "$pid_childs" + [ "$pid_childs" != "" ] && kill -9 $pid_childs } - + pidof_cwmp() { local pids="" pids="`ps | grep /usr/sbin/cwmpd | sed 's/^ \+//g' | sed 's/ \+/:/g' | grep -v \" Z \" | grep -v grep | cut -f1 -d: | tr '\n' ' '`" @@ -182,22 +177,17 @@ pidof_freecwmp() { } stop_freecwmp_cache() { - local pid_list="" pid="" pids="" found="1" p name state ppid rest cmd + local pid_list="" pid="" pids="" p name state ppid rest cmd - while [ "$found" = "1" ]; do - found="0" - pid_list="`pidof_freecwmp`" - for pid in $pid_list; do - read p name state ppid rest < /proc/$pid/stat - cmd=`cat /proc/$ppid/cmdline | grep /etc/init.d/cwmpd` - if [ "_$cmd" = "_" ]; then - continue - fi - kill -stop $ppid - found="1" - pids=`get_process_childs $ppid` - kill -9 "$pids" - done + pid_list="`pidof_freecwmp`" + for pid in $pid_list; do + read p name state ppid rest < /proc/$pid/stat + cmd=`cat /proc/$ppid/cmdline | grep /etc/init.d/cwmpd` + if [ "_$cmd" = "_" ]; then + continue + fi + kill_process_childs "$ppid" + [ "$ppid" != "" ] && kill -9 "$ppid" done } @@ -206,19 +196,12 @@ stop_cwmpd() { local pid_list="" pids="" str="" pid_list=`pidof_cwmp` if [ "_$pid_list" != "_" ]; then - pid_list=`get_process_childs "$pid_list"` - ubus call tr069 command '{"command": "exit"}' -t 3 &> /dev/null - kill -9 $pid_list - - pids="`pidof_cwmp`" - local cnt=0 - while [ "_$pids" != "_" -a $cnt -lt 100 ];do - pid_list="$pid_list $pids" - kill -stop $pid_list - pid_list=`get_process_childs "$pid_list"` + kill_process_childs "$pid_list" + ubus call tr069 command '{"command": "exit"}' -t 3 >/dev/null + local ret=$? + if [ "$ret" != "0" ]; then kill -9 $pid_list - pids="`pidof_cwmp`" - done + fi fi stop_freecwmp_cache } diff --git a/ubus.c b/ubus.c index 54adc3b..c5170a4 100644 --- a/ubus.c +++ b/ubus.c @@ -142,7 +142,8 @@ cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj, ubus_send_reply(ctx, req, b.head); blob_buf_free(&b); - + close(cwmp_main.cr_socket_desc); + CWMP_LOG(INFO,"Close connection request server socket"); error = pthread_create(&exit_thread, NULL, &thread_exit_program, NULL); if (error<0) {