mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
Increase upload curl timeout to 30 seconds and improve the code to prevent crashes
This commit is contained in:
parent
f9a7bb027a
commit
a1df16afca
4 changed files with 80 additions and 54 deletions
|
|
@ -72,6 +72,7 @@
|
||||||
#define BUF_SIZE_256 (256 + 1)
|
#define BUF_SIZE_256 (256 + 1)
|
||||||
#define BUF_SIZE_2048 (2048 + 1)
|
#define BUF_SIZE_2048 (2048 + 1)
|
||||||
|
|
||||||
|
#define ICWMP_TMP_PATH "/tmp/icwmp"
|
||||||
#define FIREWALL_CWMP "/etc/firewall.cwmp"
|
#define FIREWALL_CWMP "/etc/firewall.cwmp"
|
||||||
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/icwmp"
|
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/icwmp"
|
||||||
#define DM_PPP_INTERFACE_PATH "Device\\.PPP\\.Interface\\."
|
#define DM_PPP_INTERFACE_PATH "Device\\.PPP\\.Interface\\."
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ int download_file_in_subprocess(const char *file_path, const char *url, const ch
|
||||||
CWMP_LOG(ERROR, "download %s: url is null");
|
CWMP_LOG(ERROR, "download %s: url is null");
|
||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct blob_buf bbuf;
|
struct blob_buf bbuf;
|
||||||
CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf));
|
CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf));
|
||||||
blob_buf_init(&bbuf, 0);
|
blob_buf_init(&bbuf, 0);
|
||||||
|
|
@ -133,8 +134,9 @@ int download_file_in_subprocess(const char *file_path, const char *url, const ch
|
||||||
|
|
||||||
if (download_task != NULL) {
|
if (download_task != NULL) {
|
||||||
char *ret = execute_task_in_subprocess(download_task);
|
char *ret = execute_task_in_subprocess(download_task);
|
||||||
return atoi(ret);
|
return ret ? atoi(ret) : 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -412,7 +414,7 @@ int cwmp_apply_multiple_firmware_in_subprocess()
|
||||||
{
|
{
|
||||||
subprocess_start(apply_multiple_firmware_task_function);
|
subprocess_start(apply_multiple_firmware_task_function);
|
||||||
char *ret = execute_task_in_subprocess("{}"); //empty json object
|
char *ret = execute_task_in_subprocess("{}"); //empty json object
|
||||||
return atoi(ret);
|
return ret ? atoi(ret) : 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cwmp_launch_download(struct download *pdownload, char *download_file_name, enum load_type ltype, struct transfer_complete **ptransfer_complete)
|
int cwmp_launch_download(struct download *pdownload, char *download_file_name, enum load_type ltype, struct transfer_complete **ptransfer_complete)
|
||||||
|
|
|
||||||
|
|
@ -68,48 +68,52 @@ int subprocess_start(task_function task_fun)
|
||||||
return CWMP_GEN_ERR;
|
return CWMP_GEN_ERR;
|
||||||
|
|
||||||
pid_t p;
|
pid_t p;
|
||||||
|
|
||||||
if (pipe(pipefd1) == -1) {
|
if (pipe(pipefd1) == -1) {
|
||||||
CWMP_LOG(ERROR, "pipefd1 failed\n");
|
CWMP_LOG(ERROR, "pipefd1 failed\n");
|
||||||
return CWMP_GEN_ERR;
|
return CWMP_GEN_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe(pipefd2) == -1) {
|
if (pipe(pipefd2) == -1) {
|
||||||
CWMP_LOG(ERROR, "pipefd2 failed\n");
|
CWMP_LOG(ERROR, "pipefd2 failed\n");
|
||||||
return CWMP_GEN_ERR;
|
return CWMP_GEN_ERR;
|
||||||
}
|
}
|
||||||
p = fork();
|
|
||||||
if (p == 0) {
|
|
||||||
while(1) {
|
|
||||||
char from_parent[512];
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
read(pipefd1[0], from_parent, 512); //The received string should has the form {"task":"TaskName", "arg1_name":"xxx", "arg2_name":"xxxx"}
|
p = fork();
|
||||||
if (strlen(from_parent) == 0)
|
if (p == 0) {
|
||||||
continue;
|
while(1) {
|
||||||
//get the task name
|
char from_parent[512];
|
||||||
//if the task name is end
|
int ret = 0;
|
||||||
if (check_task_is_end(from_parent)) {
|
|
||||||
exit((write(pipefd2[1], EXIT_TASK, strlen(EXIT_TASK)+1) == -1)
|
|
||||||
? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
char *to_child = task_fun(from_parent);
|
|
||||||
|
|
||||||
struct blob_buf bbuf;
|
read(pipefd1[0], from_parent, 512); //The received string should has the form {"task":"TaskName", "arg1_name":"xxx", "arg2_name":"xxxx"}
|
||||||
CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf));
|
if (strlen(from_parent) == 0)
|
||||||
blob_buf_init(&bbuf, 0);
|
continue;
|
||||||
blobmsg_add_string(&bbuf, "ret", to_child ? to_child : "500");
|
|
||||||
char *to_child_json = blobmsg_format_json(bbuf.head, true);
|
|
||||||
|
|
||||||
ret = write(pipefd2[1], to_child_json, CWMP_STRLEN(to_child_json)+1);
|
//get the task name if the task name is end
|
||||||
|
if (check_task_is_end(from_parent)) {
|
||||||
|
exit((write(pipefd2[1], EXIT_TASK, strlen(EXIT_TASK)+1) == -1)
|
||||||
|
? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
FREE(to_child);
|
char *to_child = task_fun(from_parent);
|
||||||
FREE(to_child_json);
|
|
||||||
blob_buf_free(&bbuf);
|
|
||||||
|
|
||||||
if (ret == -1) {
|
struct blob_buf bbuf;
|
||||||
exit(EXIT_FAILURE);
|
CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf));
|
||||||
|
blob_buf_init(&bbuf, 0);
|
||||||
|
blobmsg_add_string(&bbuf, "ret", to_child ? to_child : "500");
|
||||||
|
char *to_child_json = blobmsg_format_json(bbuf.head, true);
|
||||||
|
|
||||||
|
ret = write(pipefd2[1], to_child_json, CWMP_STRLEN(to_child_json)+1);
|
||||||
|
|
||||||
|
FREE(to_child);
|
||||||
|
FREE(to_child_json);
|
||||||
|
blob_buf_free(&bbuf);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return CWMP_OK;
|
return CWMP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
67
src/upload.c
67
src/upload.c
|
|
@ -22,13 +22,13 @@
|
||||||
#include "subprocess.h"
|
#include "subprocess.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
#define CURL_TIMEOUT 20
|
#define CURL_TIMEOUT 30
|
||||||
|
|
||||||
int count_upload_queue = 0;
|
int count_upload_queue = 0;
|
||||||
|
|
||||||
LIST_HEAD(list_upload);
|
LIST_HEAD(list_upload);
|
||||||
|
|
||||||
int lookup_vcf_name(int instance, char **value)
|
static int lookup_vcf_name(int instance, char **value)
|
||||||
{
|
{
|
||||||
char vcf_name_parameter[256];
|
char vcf_name_parameter[256];
|
||||||
LIST_HEAD(vcf_parameters);
|
LIST_HEAD(vcf_parameters);
|
||||||
|
|
@ -46,7 +46,7 @@ int lookup_vcf_name(int instance, char **value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lookup_vlf_name(int instance, char **value)
|
static int lookup_vlf_name(int instance, char **value)
|
||||||
{
|
{
|
||||||
char vlf_name_parameter[256];
|
char vlf_name_parameter[256];
|
||||||
LIST_HEAD(vlf_parameters);
|
LIST_HEAD(vlf_parameters);
|
||||||
|
|
@ -67,9 +67,9 @@ int lookup_vlf_name(int instance, char **value)
|
||||||
/*
|
/*
|
||||||
* Upload file
|
* Upload file
|
||||||
*/
|
*/
|
||||||
int upload_file(const char *file_path, const char *url, const char *username, const char *password)
|
static long upload_file(const char *file_path, const char *url, const char *username, const char *password)
|
||||||
{
|
{
|
||||||
int res_code = 0;
|
long res_code = 0;
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
FILE *fd_upload;
|
FILE *fd_upload;
|
||||||
|
|
@ -77,24 +77,31 @@ int upload_file(const char *file_path, const char *url, const char *username, co
|
||||||
|
|
||||||
if (url == NULL) {
|
if (url == NULL) {
|
||||||
CWMP_LOG(ERROR, "upload %s: url is null", __FUNCTION__);
|
CWMP_LOG(ERROR, "upload %s: url is null", __FUNCTION__);
|
||||||
return -1;
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_path == NULL) {
|
if (file_path == NULL) {
|
||||||
CWMP_LOG(ERROR, "upload file name unknown");
|
CWMP_LOG(ERROR, "upload file name unknown");
|
||||||
return -1;
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != stat(file_path, &file_info)) {
|
if (!file_exists(file_path)) {
|
||||||
CWMP_LOG(ERROR, "upload file %s not exists", file_path);
|
CWMP_LOG(ERROR, "upload_file %s does not exist", file_path);
|
||||||
return -1;
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_upload = fopen(file_path, "rb");
|
fd_upload = fopen(file_path, "rb");
|
||||||
if (fd_upload == NULL) {
|
if (fd_upload == NULL) {
|
||||||
CWMP_LOG(ERROR, "Failed to open url[%s] for upload", file_path);
|
CWMP_LOG(ERROR, "Failed to open file[%s] for upload", file_path);
|
||||||
return FAULT_CPE_INTERNAL_ERROR;
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fstat(fileno(fd_upload), &file_info) != 0) {
|
||||||
|
CWMP_LOG(ERROR, "Failed to get file info for %s\n", file_path);
|
||||||
|
fclose(fd_upload);
|
||||||
|
return FAULT_CPE_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
|
|
||||||
|
|
@ -104,18 +111,20 @@ int upload_file(const char *file_path, const char *url, const char *username, co
|
||||||
snprintf(userpass, sizeof(userpass), "%s:%s", username, password ? password : "");
|
snprintf(userpass, sizeof(userpass), "%s:%s", username, password ? password : "");
|
||||||
curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
|
curl_easy_setopt(curl, CURLOPT_USERPWD, userpass);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CWMP_STRNCMP(url, "https://", 8) == 0)
|
if (CWMP_STRNCMP(url, "https://", 8) == 0)
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT);
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT);
|
||||||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
|
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
|
||||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
//curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
|
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||||
curl_easy_setopt(curl, CURLOPT_READDATA, fd_upload);
|
curl_easy_setopt(curl, CURLOPT_READDATA, fd_upload);
|
||||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
|
||||||
|
|
||||||
res = curl_easy_perform(curl);
|
res = curl_easy_perform(curl);
|
||||||
if(res != CURLE_OK) {
|
if (res != CURLE_OK) {
|
||||||
CWMP_LOG(ERROR, "## curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
CWMP_LOG(ERROR, "## curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,13 +139,13 @@ int upload_file(const char *file_path, const char *url, const char *username, co
|
||||||
|
|
||||||
char *upload_file_task_function(char *task)
|
char *upload_file_task_function(char *task)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct blob_buf bbuf;
|
struct blob_buf bbuf;
|
||||||
|
|
||||||
if (task == NULL) {
|
if (task == NULL) {
|
||||||
CWMP_LOG(ERROR, "upload %s: task is null", __FUNCTION__);
|
CWMP_LOG(ERROR, "upload %s: task is null", __FUNCTION__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf));
|
CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf));
|
||||||
blob_buf_init(&bbuf, 0);
|
blob_buf_init(&bbuf, 0);
|
||||||
|
|
||||||
|
|
@ -156,10 +165,13 @@ char *upload_file_task_function(char *task)
|
||||||
char *username = blobmsg_get_string(tb[3]);
|
char *username = blobmsg_get_string(tb[3]);
|
||||||
char *password = blobmsg_get_string(tb[4]);
|
char *password = blobmsg_get_string(tb[4]);
|
||||||
|
|
||||||
int http_code = upload_file(file_path, url, username, password);
|
long http_code = upload_file(file_path, url, username, password);
|
||||||
char *http_ret = (char *)malloc(4 * sizeof(char));
|
char *http_ret = (char *)malloc(16 * sizeof(char));
|
||||||
snprintf(http_ret, 4, "%d", http_code);
|
if (http_ret == NULL)
|
||||||
http_ret[3] = 0;
|
return NULL;
|
||||||
|
|
||||||
|
snprintf(http_ret, 16, "%ld", http_code);
|
||||||
|
|
||||||
return http_ret;
|
return http_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +196,7 @@ int upload_file_in_subprocess(const char *file_path, const char *url, const char
|
||||||
|
|
||||||
if (upload_task != NULL) {
|
if (upload_task != NULL) {
|
||||||
char *ret = execute_task_in_subprocess(upload_task);
|
char *ret = execute_task_in_subprocess(upload_task);
|
||||||
return atoi(ret);
|
return ret ? atoi(ret) : 500;
|
||||||
}
|
}
|
||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
|
@ -201,16 +213,23 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
|
||||||
bkp_session_save();
|
bkp_session_save();
|
||||||
char err_msg[256] = {0};
|
char err_msg[256] = {0};
|
||||||
|
|
||||||
|
if (!folder_exists(ICWMP_TMP_PATH)) {
|
||||||
|
int status = mkdir(ICWMP_TMP_PATH, S_IRWXU);
|
||||||
|
if (status != 0) {
|
||||||
|
snprintf(err_msg, sizeof(err_msg), "Failed to create (%s) folder", ICWMP_TMP_PATH);
|
||||||
|
goto end_upload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pupload->file_type[0] == '1') {
|
if (pupload->file_type[0] == '1') {
|
||||||
snprintf(file_path, sizeof(file_path), "/tmp/all_configs");
|
snprintf(file_path, sizeof(file_path), "%s/all_configs", ICWMP_TMP_PATH);
|
||||||
cwmp_uci_init();
|
cwmp_uci_init();
|
||||||
cwmp_uci_export(file_path, UCI_STANDARD_CONFIG);
|
cwmp_uci_export(file_path, UCI_STANDARD_CONFIG);
|
||||||
cwmp_uci_exit();
|
cwmp_uci_exit();
|
||||||
} else if (pupload->file_type[0] == '2') {
|
} else if (pupload->file_type[0] == '2') {
|
||||||
lookup_vlf_name(1, &name);
|
lookup_vlf_name(1, &name);
|
||||||
if (name && strlen(name) > 0) {
|
if (name && strlen(name) > 0) {
|
||||||
snprintf(file_path, sizeof(file_path), "/tmp/messages");
|
snprintf(file_path, sizeof(file_path), "%s/messages", ICWMP_TMP_PATH);
|
||||||
// cppcheck-suppress uninitvar
|
|
||||||
if (copy(name, file_path) != 0) {
|
if (copy(name, file_path) != 0) {
|
||||||
error = FAULT_CPE_UPLOAD_FAILURE;
|
error = FAULT_CPE_UPLOAD_FAILURE;
|
||||||
snprintf(err_msg, sizeof(err_msg), "Failed to copy the file content from %s to %s", file_path, name);
|
snprintf(err_msg, sizeof(err_msg), "Failed to copy the file content from %s to %s", file_path, name);
|
||||||
|
|
@ -223,7 +242,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
|
||||||
} else if (pupload->file_type[0] == '3') {
|
} else if (pupload->file_type[0] == '3') {
|
||||||
lookup_vcf_name(pupload->f_instance, &name);
|
lookup_vcf_name(pupload->f_instance, &name);
|
||||||
if (name && strlen(name) > 0) {
|
if (name && strlen(name) > 0) {
|
||||||
snprintf(file_path, sizeof(file_path), "/tmp/%s", name);
|
snprintf(file_path, sizeof(file_path), "%s/%s", ICWMP_TMP_PATH, name);
|
||||||
cwmp_uci_init();
|
cwmp_uci_init();
|
||||||
cwmp_uci_export_package(name, file_path, UCI_STANDARD_CONFIG);
|
cwmp_uci_export_package(name, file_path, UCI_STANDARD_CONFIG);
|
||||||
cwmp_uci_exit();
|
cwmp_uci_exit();
|
||||||
|
|
@ -236,7 +255,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans
|
||||||
} else { //file_type is 4
|
} else { //file_type is 4
|
||||||
lookup_vlf_name(pupload->f_instance, &name);
|
lookup_vlf_name(pupload->f_instance, &name);
|
||||||
if (name && strlen(name) > 0) {
|
if (name && strlen(name) > 0) {
|
||||||
snprintf(file_path, sizeof(file_path), "/tmp/.cwmp_upload");
|
snprintf(file_path, sizeof(file_path), "%s/.cwmp_upload", ICWMP_TMP_PATH);
|
||||||
if (copy(name, file_path) != 0) {
|
if (copy(name, file_path) != 0) {
|
||||||
error = FAULT_CPE_UPLOAD_FAILURE;
|
error = FAULT_CPE_UPLOAD_FAILURE;
|
||||||
snprintf(err_msg, sizeof(err_msg), "Failed to copy the file content from %s to %s", file_path, name);
|
snprintf(err_msg, sizeof(err_msg), "Failed to copy the file content from %s to %s", file_path, name);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue