Remove most memory leaks with valgrind

This commit is contained in:
2023-01-11 16:38:14 +01:00
parent 32f00175e4
commit 487386158d
7 changed files with 68 additions and 42 deletions

View File

@ -36,7 +36,7 @@ bin/res:
mkdir -p bin/res mkdir -p bin/res
bin/test: test/mock_*.c test/test_*.c \ bin/test: test/mock_*.c test/test_*.c \
src/lib/utils.c src/lib/sock.c src/lib/list.c src/lib/http.c src/lib/http_static.c src/logger.c src/lib/utils.c src/lib/sock.c src/lib/list.c src/lib/http.c src/lib/http_static.c src/logger.c src/lib/error.c
$(CC) -o $@ $(CFLAGS) $^ -lcriterion $(CC) -o $@ $(CFLAGS) $^ -lcriterion

View File

@ -69,6 +69,9 @@ int compress_free(compress_ctx *ctx) {
BrotliEncoderDestroyInstance(ctx->brotli); BrotliEncoderDestroyInstance(ctx->brotli);
ctx->brotli = NULL; ctx->brotli = NULL;
} }
if (ctx->mode & COMPRESS_GZ) {
deflateEnd(&ctx->gzip);
}
ctx->mode = 0; ctx->mode = 0;
return 0; return 0;
} }

View File

@ -42,7 +42,7 @@ int config_load(const char *filename) {
if (comment != NULL) comment[0] = 0; if (comment != NULL) comment[0] = 0;
unsigned long len = strlen(ptr); unsigned long len = strlen(ptr);
char *end_ptr = ptr + len - 1; char *end_ptr = (len > 0) ? ptr + len - 1 : ptr;
while (end_ptr[0] == ' ' || end_ptr[0] == '\t') { while (end_ptr[0] == ' ' || end_ptr[0] == '\t') {
end_ptr[0] = 0; end_ptr[0] = 0;
end_ptr--; end_ptr--;
@ -161,6 +161,8 @@ int config_load(const char *filename) {
if (strlen(source) == 0) { if (strlen(source) == 0) {
err: err:
critical("Unable to parse config file (line %i)", line); critical("Unable to parse config file (line %i)", line);
free(line);
fclose(file);
return -2; return -2;
} }
@ -182,6 +184,7 @@ int config_load(const char *filename) {
} }
free(line); free(line);
fclose(file);
for (int k = 0; k < i; k++) { for (int k = 0; k < i; k++) {
host_config_t *hc = &config.hosts[k]; host_config_t *hc = &config.hosts[k];

View File

@ -6,6 +6,8 @@
#include <errno.h> #include <errno.h>
#define FACTOR 4 #define FACTOR 4
#define meta(ptr) ((list_meta_t *) ((unsigned char *) (ptr) - sizeof(list_meta_t)))
#define data(ptr) ((unsigned char *) (ptr) + sizeof(list_meta_t))
typedef struct { typedef struct {
int init_size, elem_size, max_size, size; int init_size, elem_size, max_size, size;
@ -30,21 +32,24 @@ void *list_create(int elem_size, int init_elem_n) {
} }
void *list_ptr = malloc(sizeof(list_meta_t) + elem_size * init_elem_n); void *list_ptr = malloc(sizeof(list_meta_t) + elem_size * init_elem_n);
if (list_ptr == NULL)
return NULL;
memset(list_ptr, 0, sizeof(list_meta_t) + elem_size * init_elem_n);
list_meta_t *list = list_ptr; list_meta_t *list = list_ptr;
list->init_size = init_elem_n; list->init_size = init_elem_n;
list->elem_size = elem_size; list->elem_size = elem_size;
list->max_size = init_elem_n; list->max_size = init_elem_n;
list->size = 0; list->size = 0;
return (unsigned char *) list_ptr + sizeof(list_meta_t); return data(list_ptr);
} }
int list_size(const void *list_ptr) { int list_size(const void *list_ptr) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); return meta(list_ptr)->size;
return list->size;
} }
int list_find(void *list_ptr, void *elem) { int list_find(void *list_ptr, void *elem) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); list_meta_t *list = meta(list_ptr);
unsigned char *array = list_ptr; unsigned char *array = list_ptr;
for (int i = 0; i < list->size; i++) { for (int i = 0; i < list->size; i++) {
@ -60,32 +65,31 @@ void *list_insert(void *list_ptr, void *elem, int n) {
void *ptr = NULL; void *ptr = NULL;
list_ptr = list_insert_ptr(list_ptr, &ptr, n); list_ptr = list_insert_ptr(list_ptr, &ptr, n);
if (list_ptr != NULL && ptr != NULL) { if (list_ptr != NULL && ptr != NULL) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); memcpy(ptr, elem, meta(list_ptr)->elem_size);
memcpy(ptr, elem, list->elem_size);
} }
return list_ptr; return list_ptr;
} }
void *list_insert_ptr(void *list_ptr, void **elem, int n) { void *list_insert_ptr(void *list_ptr, void **elem, int n) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); list_meta_t *list = meta(list_ptr);
if (n < 0) if (n < 0)
n = list->size + n + 1; n = list->size + n + 1;
if (list->size >= list->max_size) { if (list->size >= list->max_size) {
if ((list = list_resize(list, list->max_size * FACTOR)) == NULL) { if ((list = list_resize(list, list->max_size * FACTOR)) == NULL)
return NULL; return NULL;
}
} }
unsigned char *array = (unsigned char *) list + sizeof(list_meta_t); unsigned char *array = data(list);
if (n < list->size) if (n < list->size)
memmove(array + (n + 1) * list->elem_size, array + n * list->elem_size, (list->size - n) * list->elem_size); memmove(array + (n + 1) * list->elem_size, array + n * list->elem_size, (list->size - n) * list->elem_size);
*elem = array + n * list->elem_size; *elem = array + n * list->elem_size;
memset(*elem, 0, list->elem_size);
list->size++; list->size++;
return (unsigned char *) list + sizeof(list_meta_t); return array;
} }
void *list_append(void *list_ptr, void *elem) { void *list_append(void *list_ptr, void *elem) {
@ -97,7 +101,7 @@ void *list_append_ptr(void *list_ptr, void **elem) {
} }
void *list_remove(void *list_ptr, int n) { void *list_remove(void *list_ptr, int n) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); list_meta_t *list = meta(list_ptr);
if (n < 0) if (n < 0)
n = list->size + n; n = list->size + n;
@ -106,6 +110,8 @@ void *list_remove(void *list_ptr, int n) {
if (list->size > 1 && n < list->size) if (list->size > 1 && n < list->size)
memmove(array + n * list->elem_size, array + (n + 1) * list->elem_size, (list->size - n - 1) * list->elem_size); memmove(array + n * list->elem_size, array + (n + 1) * list->elem_size, (list->size - n - 1) * list->elem_size);
memset(array + list->size * list->elem_size, 0, list->elem_size);
list->size--; list->size--;
if (list->size < list->max_size / FACTOR / 2 && list->max_size / FACTOR >= list->init_size) { if (list->size < list->max_size / FACTOR / 2 && list->max_size / FACTOR >= list->init_size) {
if ((list = list_resize(list, list->max_size / FACTOR)) == NULL) { if ((list = list_resize(list, list->max_size / FACTOR)) == NULL) {
@ -113,7 +119,7 @@ void *list_remove(void *list_ptr, int n) {
} }
} }
return (unsigned char *) list + sizeof(list_meta_t); return data(list);
} }
void *list_delete(void *list_ptr, void *elem) { void *list_delete(void *list_ptr, void *elem) {
@ -126,14 +132,13 @@ void *list_delete(void *list_ptr, void *elem) {
} }
void *list_clear(void *list_ptr) { void *list_clear(void *list_ptr) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); list_meta_t *list = meta(list_ptr);
list->size = 0; list->size = 0;
memset(list_ptr, 0, list->max_size * list->elem_size); memset(list_ptr, 0, list->max_size * list->elem_size);
list->max_size = list->init_size; list->max_size = list->init_size;
return (unsigned char *) list_resize(list, list->max_size * list->elem_size) + sizeof(list_meta_t); return data(list_resize(list, list->max_size));
} }
void list_free(void *list_ptr) { void list_free(void *list_ptr) {
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t)); free(meta(list_ptr));
free(list);
} }

View File

@ -462,7 +462,7 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu
return -1; return -1;
} }
ret = sock_recv(&proxy->proxy, buffer, sizeof(buffer), MSG_PEEK); ret = sock_recv(&proxy->proxy, buffer, sizeof(buffer) - 1, MSG_PEEK);
if (ret <= 0) { if (ret <= 0) {
int e_sys = error_get_sys(), e_ssl = error_get_ssl(); int e_sys = error_get_sys(), e_ssl = error_get_ssl();
if (e_sys == EAGAIN || e_sys == EINPROGRESS || e_ssl == SSL_ERROR_WANT_READ || e_ssl == SSL_ERROR_WANT_WRITE) { if (e_sys == EAGAIN || e_sys == EINPROGRESS || e_ssl == SSL_ERROR_WANT_READ || e_ssl == SSL_ERROR_WANT_WRITE) {
@ -477,6 +477,7 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu
retry = tries < 4; retry = tries < 4;
goto proxy_err; goto proxy_err;
} }
buffer[ret] = 0;
char *buf = buffer; char *buf = buffer;
unsigned short header_len = (unsigned short) (strstr(buffer, "\r\n\r\n") - buffer + 4); unsigned short header_len = (unsigned short) (strstr(buffer, "\r\n\r\n") - buffer + 4);

View File

@ -79,15 +79,18 @@ static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) {
} }
void server_free_client(client_ctx_t *ctx) { void server_free_client(client_ctx_t *ctx) {
for (int i = 0; i < list_size(clients); i++) { clients = list_delete(clients, &ctx);
if (clients[i] == ctx) {
clients = list_remove(clients, i);
break;
}
}
free(ctx); free(ctx);
} }
static void ssl_free() {
for (int i = 0; i < CONFIG_MAX_CERT_CONFIG; i++) {
const cert_config_t *conf = &config.certs[i];
if (conf->name[0] == 0) break;
SSL_CTX_free(contexts[i]);
}
}
static void accept_cb(void *arg) { static void accept_cb(void *arg) {
int i = (int) (((int *) arg) - sockets); int i = (int) (((int *) arg) - sockets);
int fd = sockets[i]; int fd = sockets[i];
@ -98,14 +101,6 @@ static void accept_cb(void *arg) {
errno = 0; errno = 0;
return; return;
} }
clients = list_append(clients, &client_ctx);
if (clients == NULL) {
critical("Unable to add client context to list");
errno = 0;
return;
}
client_ctx->in_use = 1; client_ctx->in_use = 1;
sock *client = &client_ctx->socket; sock *client = &client_ctx->socket;
@ -124,6 +119,13 @@ static void accept_cb(void *arg) {
client_ctx->cnx_s = client->ts_start; client_ctx->cnx_s = client->ts_start;
client_ctx->cnx_e = -1, client_ctx->req_s = -1, client_ctx->req_e = -1, client_ctx->res_ts = -1; client_ctx->cnx_e = -1, client_ctx->req_s = -1, client_ctx->req_e = -1, client_ctx->res_ts = -1;
clients = list_append(clients, &client_ctx);
if (clients == NULL) {
critical("Unable to add client context to list");
errno = 0;
return;
}
tcp_accept(client_ctx); tcp_accept(client_ctx);
} }
@ -160,9 +162,9 @@ static void terminate_gracefully(int sig) {
workers_stop(); workers_stop();
workers_destroy(); workers_destroy();
for (int i = 0; i < list_size(clients); i++) { while (list_size(clients) > 0)
tcp_close(clients[i]); server_free_client(clients[0]);
}
proxy_close_all(); proxy_close_all();
logger_set_prefix(""); logger_set_prefix("");
@ -177,11 +179,6 @@ int main(int argc, char *const argv[]) {
int mode = 0; int mode = 0;
memset(sockets, 0, sizeof(sockets)); memset(sockets, 0, sizeof(sockets));
clients = list_create(sizeof(void *), 64);
if (clients == NULL) {
critical("Unable to initialize client list");
return 1;
}
const struct sockaddr_in6 addresses[2] = { const struct sockaddr_in6 addresses[2] = {
{.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(80)}, {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(80)},
@ -309,15 +306,26 @@ int main(int argc, char *const argv[]) {
} }
} }
clients = list_create(sizeof(client_ctx_t *), 64);
if (clients == NULL) {
critical("Unable to initialize client list");
ssl_free();
return 1;
}
if (async_init() != 0) { if (async_init() != 0) {
critical("Unable to initialize async thread"); critical("Unable to initialize async thread");
ssl_free();
geoip_free(); geoip_free();
list_free(clients);
return 1; return 1;
} }
if (proxy_preload() != 0) { if (proxy_preload() != 0) {
critical("Unable to initialize proxy"); critical("Unable to initialize proxy");
ssl_free();
geoip_free(); geoip_free();
list_free(clients);
async_free(); async_free();
return 1; return 1;
} }
@ -325,7 +333,10 @@ int main(int argc, char *const argv[]) {
for (int i = 0; i < NUM_SOCKETS; i++) { for (int i = 0; i < NUM_SOCKETS; i++) {
if (listen(sockets[i], LISTEN_BACKLOG) < 0) { if (listen(sockets[i], LISTEN_BACKLOG) < 0) {
critical("Unable to listen on socket %i", i); critical("Unable to listen on socket %i", i);
ssl_free();
geoip_free(); geoip_free();
list_free(clients);
async_free();
proxy_unload(); proxy_unload();
return 1; return 1;
} }
@ -347,6 +358,7 @@ int main(int argc, char *const argv[]) {
notice("Goodbye!"); notice("Goodbye!");
// cleanup // cleanup
ssl_free();
list_free(clients); list_free(clients);
geoip_free(); geoip_free();
proxy_unload(); proxy_unload();

View File

@ -29,12 +29,14 @@ void proxy_handler_func(client_ctx_t *ctx) {
if (ret == 1) { if (ret == 1) {
proxy_unlock_ctx(ctx->proxy); proxy_unlock_ctx(ctx->proxy);
ctx->proxy->client = NULL;
ctx->proxy = NULL; ctx->proxy = NULL;
} else if (ctx->use_proxy == 0) { } else if (ctx->use_proxy == 0) {
proxy_close(ctx->proxy); proxy_close(ctx->proxy);
} else if (ctx->use_proxy == 1) { } else if (ctx->use_proxy == 1) {
proxy_handler_2(ctx); proxy_handler_2(ctx);
proxy_unlock_ctx(ctx->proxy); proxy_unlock_ctx(ctx->proxy);
ctx->proxy->client = NULL;
ctx->proxy = NULL; ctx->proxy = NULL;
} else if (ctx->use_proxy == 2) { } else if (ctx->use_proxy == 2) {
// WebSocket // WebSocket