mirror of
https://github.com/pi-hole/FTL.git
synced 2025-12-20 03:18:25 +00:00
Improve memory handling in a few places. This is the result of a valgrind/memcheck test.
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
1
build.sh
1
build.sh
@@ -181,7 +181,6 @@ fi
|
|||||||
# If we are asked to run tests, we do this here
|
# If we are asked to run tests, we do this here
|
||||||
if [[ -n "${test}" ]]; then
|
if [[ -n "${test}" ]]; then
|
||||||
cd ..
|
cd ..
|
||||||
bash test/arch_test.sh
|
|
||||||
bash test/run.sh
|
bash test/run.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -718,7 +718,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
if(new_item->f & FLAG_READ_ONLY && cJSON_IsBool(elem) && elem->valueint == 1)
|
if(new_item->f & FLAG_READ_ONLY && cJSON_IsBool(elem) && elem->valueint == 1)
|
||||||
{
|
{
|
||||||
char *key = strdup(new_item->k);
|
char *key = strdup(new_item->k);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error_free(api, 400,
|
return send_json_error_free(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
"This config option can only be set in pihole.toml, not via the API",
|
"This config option can only be set in pihole.toml, not via the API",
|
||||||
@@ -740,7 +740,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
char *hint = calloc(strlen(new_item->k) + strlen(response) + 3, sizeof(char));
|
char *hint = calloc(strlen(new_item->k) + strlen(response) + 3, sizeof(char));
|
||||||
if(hint == NULL)
|
if(hint == NULL)
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error(api, 500,
|
return send_json_error(api, 500,
|
||||||
"internal_error",
|
"internal_error",
|
||||||
"Failed to allocate memory for hint",
|
"Failed to allocate memory for hint",
|
||||||
@@ -749,7 +749,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
strcpy(hint, new_item->k);
|
strcpy(hint, new_item->k);
|
||||||
strcat(hint, ": ");
|
strcat(hint, ": ");
|
||||||
strcat(hint, response);
|
strcat(hint, response);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error_free(api, 400,
|
return send_json_error_free(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
"Config item is invalid",
|
"Config item is invalid",
|
||||||
@@ -764,7 +764,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
if(new_item->f & FLAG_ENV_VAR && !compare_config_item(conf_item->t, &new_item->v, &conf_item->v))
|
if(new_item->f & FLAG_ENV_VAR && !compare_config_item(conf_item->t, &new_item->v, &conf_item->v))
|
||||||
{
|
{
|
||||||
char *key = strdup(new_item->k);
|
char *key = strdup(new_item->k);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error_free(api, 400,
|
return send_json_error_free(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
"Config items set via environment variables cannot be changed via the API",
|
"Config items set via environment variables cannot be changed via the API",
|
||||||
@@ -789,7 +789,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
char errbuf[VALIDATOR_ERRBUF_LEN] = { 0 };
|
char errbuf[VALIDATOR_ERRBUF_LEN] = { 0 };
|
||||||
if(!conf_item->c(&new_item->v, new_item->k, errbuf))
|
if(!conf_item->c(&new_item->v, new_item->k, errbuf))
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error(api, 400,
|
return send_json_error(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
"Config item validation failed",
|
"Config item validation failed",
|
||||||
@@ -832,7 +832,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error(api, 400,
|
return send_json_error(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
"Invalid configuration",
|
"Invalid configuration",
|
||||||
@@ -856,7 +856,7 @@ static int api_config_patch(struct ftl_conn *api)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Nothing changed, merely release copied config memory
|
// Nothing changed, merely release copied config memory
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
log_info("No config changes detected");
|
log_info("No config changes detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -932,7 +932,7 @@ static int api_config_put_delete(struct ftl_conn *api)
|
|||||||
if(new_item->f & FLAG_ENV_VAR)
|
if(new_item->f & FLAG_ENV_VAR)
|
||||||
{
|
{
|
||||||
char *key = strdup(new_item->k);
|
char *key = strdup(new_item->k);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
free_config_path(requested_path);
|
free_config_path(requested_path);
|
||||||
return send_json_error_free(api, 400,
|
return send_json_error_free(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
@@ -992,7 +992,7 @@ static int api_config_put_delete(struct ftl_conn *api)
|
|||||||
char errbuf[VALIDATOR_ERRBUF_LEN] = { 0 };
|
char errbuf[VALIDATOR_ERRBUF_LEN] = { 0 };
|
||||||
if(!new_item->c(&new_item->v, new_item->k, errbuf))
|
if(!new_item->c(&new_item->v, new_item->k, errbuf))
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
free_config_path(requested_path);
|
free_config_path(requested_path);
|
||||||
return send_json_error(api, 400,
|
return send_json_error(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
@@ -1018,7 +1018,7 @@ static int api_config_put_delete(struct ftl_conn *api)
|
|||||||
// Error 404 if config element not found
|
// Error 404 if config element not found
|
||||||
if(!found)
|
if(!found)
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
cJSON *json = JSON_NEW_OBJECT();
|
cJSON *json = JSON_NEW_OBJECT();
|
||||||
JSON_SEND_OBJECT_CODE(json, 404);
|
JSON_SEND_OBJECT_CODE(json, 404);
|
||||||
}
|
}
|
||||||
@@ -1026,7 +1026,7 @@ static int api_config_put_delete(struct ftl_conn *api)
|
|||||||
// Error 400 if unique item already present
|
// Error 400 if unique item already present
|
||||||
if(message != NULL)
|
if(message != NULL)
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return send_json_error(api, 400,
|
return send_json_error(api, 400,
|
||||||
"bad_request",
|
"bad_request",
|
||||||
message,
|
message,
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ static int api_network_devices_GET(struct ftl_conn *api)
|
|||||||
{
|
{
|
||||||
networkTable_readDevicesFinalize(device_stmt);
|
networkTable_readDevicesFinalize(device_stmt);
|
||||||
dbclose(&db);
|
dbclose(&db);
|
||||||
|
|
||||||
// Add SQL message (may be NULL = not available)
|
// Add SQL message (may be NULL = not available)
|
||||||
return send_json_error(api, 500,
|
return send_json_error(api, 500,
|
||||||
"database_error",
|
"database_error",
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
// uname()
|
// uname()
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
// nlroutes(), nladdrs(), nllinks()
|
|
||||||
#include "tools/netlink.h"
|
|
||||||
// struct proc_mem, getProcessMemory()
|
// struct proc_mem, getProcessMemory()
|
||||||
#include "procps.h"
|
#include "procps.h"
|
||||||
// getcpu_percentage()
|
// getcpu_percentage()
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ int set_config_from_CLI(const char *key, const char *value)
|
|||||||
if(item->f & FLAG_ENV_VAR)
|
if(item->f & FLAG_ENV_VAR)
|
||||||
{
|
{
|
||||||
log_err("Config option %s is read-only (set via environmental variable)", key);
|
log_err("Config option %s is read-only (set via environmental variable)", key);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return ENV_VAR_FORCED;
|
return ENV_VAR_FORCED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,7 +435,7 @@ int set_config_from_CLI(const char *key, const char *value)
|
|||||||
if(item->f & FLAG_READ_ONLY)
|
if(item->f & FLAG_READ_ONLY)
|
||||||
{
|
{
|
||||||
log_err("Config option %s can only be set in pihole.toml, not via the CLI", key);
|
log_err("Config option %s can only be set in pihole.toml, not via the CLI", key);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,14 +459,14 @@ int set_config_from_CLI(const char *key, const char *value)
|
|||||||
log_err(" - %s", matches[i]);
|
log_err(" - %s", matches[i]);
|
||||||
free(matches);
|
free(matches);
|
||||||
|
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return KEY_UNKNOWN;
|
return KEY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse value
|
// Parse value
|
||||||
if(!readStringValue(new_item, value, &newconf))
|
if(!readStringValue(new_item, value, &newconf))
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return VALUE_INVALID;
|
return VALUE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +484,7 @@ int set_config_from_CLI(const char *key, const char *value)
|
|||||||
char errbuf[VALIDATOR_ERRBUF_LEN] = { 0 };
|
char errbuf[VALIDATOR_ERRBUF_LEN] = { 0 };
|
||||||
if(!new_item->c(&new_item->v, new_item->k, errbuf))
|
if(!new_item->c(&new_item->v, new_item->k, errbuf))
|
||||||
{
|
{
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
log_err("Invalid value: %s", errbuf);
|
log_err("Invalid value: %s", errbuf);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
@@ -498,7 +498,7 @@ int set_config_from_CLI(const char *key, const char *value)
|
|||||||
{
|
{
|
||||||
// Test failed
|
// Test failed
|
||||||
log_debug(DEBUG_CONFIG, "Config item %s: dnsmasq config test failed", conf_item->k);
|
log_debug(DEBUG_CONFIG, "Config item %s: dnsmasq config test failed", conf_item->k);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
return DNSMASQ_TEST_FAILED;
|
return DNSMASQ_TEST_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,7 +519,7 @@ int set_config_from_CLI(const char *key, const char *value)
|
|||||||
{
|
{
|
||||||
// No change
|
// No change
|
||||||
log_debug(DEBUG_CONFIG, "Config item %s: Unchanged", conf_item->k);
|
log_debug(DEBUG_CONFIG, "Config item %s: Unchanged", conf_item->k);
|
||||||
free_config(&newconf);
|
free_config(&newconf, false);
|
||||||
|
|
||||||
// Print value
|
// Print value
|
||||||
writeTOMLvalue(stdout, -1, conf_item->t, &conf_item->v);
|
writeTOMLvalue(stdout, -1, conf_item->t, &conf_item->v);
|
||||||
|
|||||||
@@ -334,14 +334,14 @@ bool compare_config_item(const enum conf_type t, const union conf_value *val1, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void free_config(struct config *conf)
|
void free_config(struct config *conf, const bool terminating)
|
||||||
{
|
{
|
||||||
// Post-processing:
|
// Post-processing:
|
||||||
// Initialize and verify config data
|
// Initialize and verify config data
|
||||||
for(unsigned int i = 0; i < CONFIG_ELEMENTS; i++)
|
for(unsigned int i = 0; i < CONFIG_ELEMENTS; i++)
|
||||||
{
|
{
|
||||||
// Get pointer to memory location of this conf_item (copy)
|
// Get pointer to memory location of this conf_item
|
||||||
struct conf_item *copy_item = get_conf_item(conf, i);
|
struct conf_item *conf_item = get_conf_item(conf, i);
|
||||||
|
|
||||||
// Free allowed values (if defined)
|
// Free allowed values (if defined)
|
||||||
// Note: This is no necessary as we simply leave the allowed values
|
// Note: This is no necessary as we simply leave the allowed values
|
||||||
@@ -350,7 +350,7 @@ void free_config(struct config *conf)
|
|||||||
// if(conf->a != NULL) cJSON_Delete(conf->a);
|
// if(conf->a != NULL) cJSON_Delete(conf->a);
|
||||||
|
|
||||||
// Make a type-dependent copy of the value
|
// Make a type-dependent copy of the value
|
||||||
switch(copy_item->t)
|
switch(conf_item->t)
|
||||||
{
|
{
|
||||||
case CONF_BOOL:
|
case CONF_BOOL:
|
||||||
case CONF_INT:
|
case CONF_INT:
|
||||||
@@ -375,12 +375,19 @@ void free_config(struct config *conf)
|
|||||||
// Nothing to do
|
// Nothing to do
|
||||||
break;
|
break;
|
||||||
case CONF_STRING_ALLOCATED:
|
case CONF_STRING_ALLOCATED:
|
||||||
free(copy_item->v.s);
|
free(conf_item->v.s);
|
||||||
copy_item->v.s = NULL;
|
conf_item->v.s = NULL;
|
||||||
copy_item->t = CONF_STRING; // not allocated anymore
|
conf_item->t = CONF_STRING; // not allocated anymore
|
||||||
break;
|
break;
|
||||||
case CONF_JSON_STRING_ARRAY:
|
case CONF_JSON_STRING_ARRAY:
|
||||||
cJSON_Delete(copy_item->v.json);
|
// Delete default JSON only when terminating.
|
||||||
|
// During config replacements, it is simply
|
||||||
|
// handed over from the old to the new config
|
||||||
|
// structure to avoid unnecessary memory
|
||||||
|
// duplications
|
||||||
|
if(terminating)
|
||||||
|
cJSON_Delete(conf_item->d.json);
|
||||||
|
cJSON_Delete(conf_item->v.json);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1043,12 +1050,12 @@ void initConfig(struct config *conf)
|
|||||||
conf->webserver.headers.t = CONF_JSON_STRING_ARRAY;
|
conf->webserver.headers.t = CONF_JSON_STRING_ARRAY;
|
||||||
conf->webserver.headers.f = FLAG_RESTART_FTL;
|
conf->webserver.headers.f = FLAG_RESTART_FTL;
|
||||||
conf->webserver.headers.d.json = cJSON_CreateArray();
|
conf->webserver.headers.d.json = cJSON_CreateArray();
|
||||||
cJSON_AddItemReferenceToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-DNS-Prefetch-Control: off"));
|
cJSON_AddItemToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-DNS-Prefetch-Control: off"));
|
||||||
cJSON_AddItemReferenceToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"));
|
cJSON_AddItemToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"));
|
||||||
cJSON_AddItemReferenceToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-Frame-Options: DENY"));
|
cJSON_AddItemToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-Frame-Options: DENY"));
|
||||||
cJSON_AddItemReferenceToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-XSS-Protection: 0"));
|
cJSON_AddItemToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-XSS-Protection: 0"));
|
||||||
cJSON_AddItemReferenceToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-Content-Type-Options: nosniff"));
|
cJSON_AddItemToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("X-Content-Type-Options: nosniff"));
|
||||||
cJSON_AddItemReferenceToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("Referrer-Policy: strict-origin-when-cross-origin"));
|
cJSON_AddItemToArray(conf->webserver.headers.d.json, cJSON_CreateStringReference("Referrer-Policy: strict-origin-when-cross-origin"));
|
||||||
conf->webserver.headers.c = validate_stub; // Only type-based checking
|
conf->webserver.headers.c = validate_stub; // Only type-based checking
|
||||||
|
|
||||||
conf->webserver.serve_all.k = "webserver.serve_all";
|
conf->webserver.serve_all.k = "webserver.serve_all";
|
||||||
@@ -1067,7 +1074,7 @@ void initConfig(struct config *conf)
|
|||||||
|
|
||||||
conf->webserver.session.restore.k = "webserver.session.restore";
|
conf->webserver.session.restore.k = "webserver.session.restore";
|
||||||
conf->webserver.session.restore.h = "Should Pi-hole backup and restore sessions from the database? This is useful if you want to keep your sessions after a restart of the web interface.";
|
conf->webserver.session.restore.h = "Should Pi-hole backup and restore sessions from the database? This is useful if you want to keep your sessions after a restart of the web interface.";
|
||||||
conf->webserver.session.restore.a = cJSON_CreateStringReference("true or false");
|
conf->webserver.session.restore.a = cJSON_CreateStringReference("true or false");
|
||||||
conf->webserver.session.restore.t = CONF_BOOL;
|
conf->webserver.session.restore.t = CONF_BOOL;
|
||||||
conf->webserver.session.restore.d.b = true;
|
conf->webserver.session.restore.d.b = true;
|
||||||
conf->webserver.session.restore.c = validate_stub; // Only type-based checking
|
conf->webserver.session.restore.c = validate_stub; // Only type-based checking
|
||||||
@@ -1665,7 +1672,6 @@ void initConfig(struct config *conf)
|
|||||||
{
|
{
|
||||||
conf_item->a = cJSON_CreateStringReference("true or false");
|
conf_item->a = cJSON_CreateStringReference("true or false");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1956,7 +1962,7 @@ void replace_config(struct config *newconf)
|
|||||||
memcpy(&config, newconf, sizeof(struct config));
|
memcpy(&config, newconf, sizeof(struct config));
|
||||||
|
|
||||||
// Free old backup struct
|
// Free old backup struct
|
||||||
free_config(&old_conf);
|
free_config(&old_conf, false);
|
||||||
|
|
||||||
// Unlock shared memory
|
// Unlock shared memory
|
||||||
unlock_shm();
|
unlock_shm();
|
||||||
@@ -2016,7 +2022,7 @@ void reread_config(void)
|
|||||||
{
|
{
|
||||||
// New configuration is invalid, restore old one
|
// New configuration is invalid, restore old one
|
||||||
log_debug(DEBUG_CONFIG, "Modified config file is invalid, discarding and overwriting with current configuration");
|
log_debug(DEBUG_CONFIG, "Modified config file is invalid, discarding and overwriting with current configuration");
|
||||||
free_config(&conf_copy);
|
free_config(&conf_copy, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the config file back to disk to ensure that all options and
|
// Write the config file back to disk to ensure that all options and
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ struct conf_item *get_conf_item(struct config *conf, const unsigned int n);
|
|||||||
struct conf_item *get_debug_item(struct config *conf, const enum debug_flag debug);
|
struct conf_item *get_debug_item(struct config *conf, const enum debug_flag debug);
|
||||||
unsigned int config_path_depth(char **paths) __attribute__ ((pure));
|
unsigned int config_path_depth(char **paths) __attribute__ ((pure));
|
||||||
void duplicate_config(struct config *dst, struct config *src);
|
void duplicate_config(struct config *dst, struct config *src);
|
||||||
void free_config(struct config *conf);
|
void free_config(struct config *conf, const bool terminating);
|
||||||
bool compare_config_item(const enum conf_type t, const union conf_value *val1, const union conf_value *val2);
|
bool compare_config_item(const enum conf_type t, const union conf_value *val1, const union conf_value *val2);
|
||||||
char **gen_config_path(const char *pathin, const char delim);
|
char **gen_config_path(const char *pathin, const char delim);
|
||||||
void free_config_path(char **paths);
|
void free_config_path(char **paths);
|
||||||
|
|||||||
18
src/daemon.c
18
src/daemon.c
@@ -65,6 +65,9 @@ void go_daemon(void)
|
|||||||
if (process_id > 0)
|
if (process_id > 0)
|
||||||
{
|
{
|
||||||
printf("FTL started!\n");
|
printf("FTL started!\n");
|
||||||
|
// Free config to silence meaningless (but still loud) memcheck
|
||||||
|
// warnings about lost memory concerning the parsed config
|
||||||
|
free_config(&config, true);
|
||||||
// Return success in exit status
|
// Return success in exit status
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -423,18 +426,21 @@ void cleanup(const int ret)
|
|||||||
// Close memory database
|
// Close memory database
|
||||||
close_memory_database();
|
close_memory_database();
|
||||||
|
|
||||||
// Remove shared memory objects
|
|
||||||
// Important: This invalidated all objects such as
|
|
||||||
// counters-> ... etc.
|
|
||||||
// This should be the last action when c
|
|
||||||
destroy_shmem();
|
|
||||||
|
|
||||||
// De-initialize the random number generator and entropy collector
|
// De-initialize the random number generator and entropy collector
|
||||||
destroy_entropy();
|
destroy_entropy();
|
||||||
|
|
||||||
// Free environment variables
|
// Free environment variables
|
||||||
freeEnvVars();
|
freeEnvVars();
|
||||||
|
|
||||||
|
// Free config
|
||||||
|
free_config(&config, true);
|
||||||
|
|
||||||
|
// Remove shared memory objects
|
||||||
|
// Important: This invalidated all objects such as
|
||||||
|
// counters-> ... etc.
|
||||||
|
// This should be the last action when cleaning up
|
||||||
|
destroy_shmem();
|
||||||
|
|
||||||
char buffer[42] = { 0 };
|
char buffer[42] = { 0 };
|
||||||
format_time(buffer, 0, timer_elapsed_msec(EXIT_TIMER));
|
format_time(buffer, 0, timer_elapsed_msec(EXIT_TIMER));
|
||||||
if(ret == RESTART_FTL_CODE)
|
if(ret == RESTART_FTL_CODE)
|
||||||
|
|||||||
@@ -359,9 +359,9 @@ static int _add_message(const enum message_type type,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3 *db;
|
sqlite3 *db = dbopen(false, false);
|
||||||
// Open database connection
|
// Open database connection
|
||||||
if((db = dbopen(false, false)) == NULL)
|
if(db == NULL)
|
||||||
// Reason for failure is logged in dbopen()
|
// Reason for failure is logged in dbopen()
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -380,8 +380,6 @@ static int _add_message(const enum message_type type,
|
|||||||
{
|
{
|
||||||
log_err("add_message(type=%u, message=%s) - Failed to bind type DELETE: %s",
|
log_err("add_message(type=%u, message=%s) - Failed to bind type DELETE: %s",
|
||||||
type, message, sqlite3_errstr(rc));
|
type, message, sqlite3_errstr(rc));
|
||||||
sqlite3_reset(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
goto end_of_add_message;
|
goto end_of_add_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,8 +388,6 @@ static int _add_message(const enum message_type type,
|
|||||||
{
|
{
|
||||||
log_err("add_message(type=%u, message=%s) - Failed to bind message DELETE: %s",
|
log_err("add_message(type=%u, message=%s) - Failed to bind message DELETE: %s",
|
||||||
type, message, sqlite3_errstr(rc));
|
type, message, sqlite3_errstr(rc));
|
||||||
sqlite3_reset(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
goto end_of_add_message;
|
goto end_of_add_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,8 +419,6 @@ static int _add_message(const enum message_type type,
|
|||||||
{
|
{
|
||||||
log_err("add_message(type=%u, message=%s) - Failed to bind type: %s",
|
log_err("add_message(type=%u, message=%s) - Failed to bind type: %s",
|
||||||
type, message, sqlite3_errstr(rc));
|
type, message, sqlite3_errstr(rc));
|
||||||
sqlite3_reset(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
goto end_of_add_message;
|
goto end_of_add_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,8 +427,6 @@ static int _add_message(const enum message_type type,
|
|||||||
{
|
{
|
||||||
log_err("add_message(type=%u, message=%s) - Failed to bind message: %s",
|
log_err("add_message(type=%u, message=%s) - Failed to bind message: %s",
|
||||||
type, message, sqlite3_errstr(rc));
|
type, message, sqlite3_errstr(rc));
|
||||||
sqlite3_reset(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
goto end_of_add_message;
|
goto end_of_add_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,15 +481,19 @@ static int _add_message(const enum message_type type,
|
|||||||
goto end_of_add_message;
|
goto end_of_add_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final database handling
|
|
||||||
sqlite3_clear_bindings(stmt);
|
|
||||||
sqlite3_reset(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
// Get row ID of the newly added message
|
|
||||||
rowid = sqlite3_last_insert_rowid(db);
|
|
||||||
|
|
||||||
end_of_add_message: // Close database connection
|
end_of_add_message: // Close database connection
|
||||||
|
|
||||||
|
// Final database handling
|
||||||
|
if(stmt != NULL)
|
||||||
|
{
|
||||||
|
sqlite3_clear_bindings(stmt);
|
||||||
|
sqlite3_reset(stmt);
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
|
// Get row ID of the newly added message
|
||||||
|
rowid = sqlite3_last_insert_rowid(db);
|
||||||
|
}
|
||||||
|
|
||||||
dbclose(&db);
|
dbclose(&db);
|
||||||
|
|
||||||
return rowid;
|
return rowid;
|
||||||
|
|||||||
@@ -1069,6 +1069,7 @@ static bool add_local_interfaces_to_network_table(sqlite3 *db, time_t now, unsig
|
|||||||
if(!nllinks(links, false))
|
if(!nllinks(links, false))
|
||||||
{
|
{
|
||||||
log_err("Failed to get links, cannot update network table");
|
log_err("Failed to get links, cannot update network table");
|
||||||
|
cJSON_Delete(links);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
log_debug(DEBUG_ARP, "Network table: Successfully read links with %i entries",
|
log_debug(DEBUG_ARP, "Network table: Successfully read links with %i entries",
|
||||||
@@ -1166,6 +1167,9 @@ static bool add_local_interfaces_to_network_table(sqlite3 *db, time_t now, unsig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free allocated memory
|
||||||
|
cJSON_Delete(link);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1544,6 +1548,9 @@ void parse_neighbor_cache(sqlite3 *db)
|
|||||||
entries++;
|
entries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free allocated JSON array
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
log_debug(DEBUG_ARP, "Network table: Finished parsing ARP cache with %u entries", entries);
|
log_debug(DEBUG_ARP, "Network table: Finished parsing ARP cache with %u entries", entries);
|
||||||
|
|
||||||
if(rc != SQLITE_OK)
|
if(rc != SQLITE_OK)
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
|||||||
{
|
{
|
||||||
// Resolve server address
|
// Resolve server address
|
||||||
int eai;
|
int eai;
|
||||||
struct addrinfo *saddr;
|
struct addrinfo *saddr = NULL;
|
||||||
// Resolve server address, port 123 is used for NTP
|
// Resolve server address, port 123 is used for NTP
|
||||||
if((eai = getaddrinfo(server, "123", NULL, &saddr)) != 0)
|
if((eai = getaddrinfo(server, "123", NULL, &saddr)) != 0)
|
||||||
{
|
{
|
||||||
@@ -494,6 +494,7 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
|||||||
}
|
}
|
||||||
errbuf[sizeof(errbuf) - 1] = '\0';
|
errbuf[sizeof(errbuf) - 1] = '\0';
|
||||||
log_ntp_message(true, false, errbuf);
|
log_ntp_message(true, false, errbuf);
|
||||||
|
freeaddrinfo(saddr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,6 +503,7 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
|||||||
if(ntp == NULL)
|
if(ntp == NULL)
|
||||||
{
|
{
|
||||||
log_err("Cannot allocate memory for NTP client");
|
log_err("Cannot allocate memory for NTP client");
|
||||||
|
freeaddrinfo(saddr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,6 +544,7 @@ bool ntp_client(const char *server, const bool settime, const bool print)
|
|||||||
|
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
freeaddrinfo(saddr);
|
freeaddrinfo(saddr);
|
||||||
|
saddr = NULL;
|
||||||
|
|
||||||
// Compute average and standard deviation
|
// Compute average and standard deviation
|
||||||
unsigned int valid = 0;
|
unsigned int valid = 0;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ static char *prefix_webhome = NULL;
|
|||||||
static char *api_uri = NULL;
|
static char *api_uri = NULL;
|
||||||
static char *admin_api_uri = NULL;
|
static char *admin_api_uri = NULL;
|
||||||
static char *login_uri = NULL;
|
static char *login_uri = NULL;
|
||||||
|
static char *webheaders = NULL;
|
||||||
|
|
||||||
// Private prototypes
|
// Private prototypes
|
||||||
static char *append_to_path(char *path, const char *append);
|
static char *append_to_path(char *path, const char *append);
|
||||||
@@ -577,7 +578,7 @@ void http_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct additional headers
|
// Construct additional headers
|
||||||
char *webheaders = strdup("");
|
webheaders = strdup("");
|
||||||
if (webheaders == NULL) {
|
if (webheaders == NULL) {
|
||||||
log_err("Failed to allocate memory for webheaders!");
|
log_err("Failed to allocate memory for webheaders!");
|
||||||
return;
|
return;
|
||||||
@@ -595,11 +596,14 @@ void http_init(void)
|
|||||||
const char *h = cJSON_GetStringValue(header);
|
const char *h = cJSON_GetStringValue(header);
|
||||||
|
|
||||||
// Allocate memory for the new header
|
// Allocate memory for the new header
|
||||||
webheaders = realloc(webheaders, strlen(webheaders) + strlen(h) + 3);
|
char *new_webheaders = realloc(webheaders, strlen(webheaders) + strlen(h) + 3);
|
||||||
if (webheaders == NULL) {
|
if (new_webheaders == NULL) {
|
||||||
log_err("Failed to allocate memory for webheaders!");
|
log_err("Failed to (re)allocate memory for webheaders!");
|
||||||
|
free(webheaders);
|
||||||
|
webheaders = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
webheaders = new_webheaders;
|
||||||
strcat(webheaders, h);
|
strcat(webheaders, h);
|
||||||
strcat(webheaders, "\r\n");
|
strcat(webheaders, "\r\n");
|
||||||
}
|
}
|
||||||
@@ -866,8 +870,11 @@ void http_terminate(void)
|
|||||||
// Free admin_api_uri path
|
// Free admin_api_uri path
|
||||||
if(admin_api_uri != NULL)
|
if(admin_api_uri != NULL)
|
||||||
free(admin_api_uri);
|
free(admin_api_uri);
|
||||||
|
|
||||||
// Free login_uri path
|
// Free login_uri path
|
||||||
if(login_uri != NULL)
|
if(login_uri != NULL)
|
||||||
free(login_uri);
|
free(login_uri);
|
||||||
|
|
||||||
|
if(webheaders != NULL)
|
||||||
|
free(webheaders);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user