Remove most memory leaks with valgrind
This commit is contained in:
2
Makefile
2
Makefile
@ -36,7 +36,7 @@ bin/res:
|
||||
mkdir -p bin/res
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -69,6 +69,9 @@ int compress_free(compress_ctx *ctx) {
|
||||
BrotliEncoderDestroyInstance(ctx->brotli);
|
||||
ctx->brotli = NULL;
|
||||
}
|
||||
if (ctx->mode & COMPRESS_GZ) {
|
||||
deflateEnd(&ctx->gzip);
|
||||
}
|
||||
ctx->mode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ int config_load(const char *filename) {
|
||||
if (comment != NULL) comment[0] = 0;
|
||||
|
||||
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') {
|
||||
end_ptr[0] = 0;
|
||||
end_ptr--;
|
||||
@ -161,6 +161,8 @@ int config_load(const char *filename) {
|
||||
if (strlen(source) == 0) {
|
||||
err:
|
||||
critical("Unable to parse config file (line %i)", line);
|
||||
free(line);
|
||||
fclose(file);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@ -182,6 +184,7 @@ int config_load(const char *filename) {
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
|
||||
for (int k = 0; k < i; k++) {
|
||||
host_config_t *hc = &config.hosts[k];
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <errno.h>
|
||||
|
||||
#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 {
|
||||
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);
|
||||
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->init_size = init_elem_n;
|
||||
list->elem_size = elem_size;
|
||||
list->max_size = init_elem_n;
|
||||
list->size = 0;
|
||||
return (unsigned char *) list_ptr + sizeof(list_meta_t);
|
||||
return data(list_ptr);
|
||||
}
|
||||
|
||||
int list_size(const void *list_ptr) {
|
||||
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t));
|
||||
return list->size;
|
||||
return meta(list_ptr)->size;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
list_ptr = list_insert_ptr(list_ptr, &ptr, n);
|
||||
if (list_ptr != NULL && ptr != NULL) {
|
||||
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t));
|
||||
memcpy(ptr, elem, list->elem_size);
|
||||
memcpy(ptr, elem, meta(list_ptr)->elem_size);
|
||||
}
|
||||
|
||||
return list_ptr;
|
||||
}
|
||||
|
||||
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)
|
||||
n = list->size + n + 1;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *array = (unsigned char *) list + sizeof(list_meta_t);
|
||||
unsigned char *array = data(list);
|
||||
|
||||
if (n < list->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;
|
||||
memset(*elem, 0, list->elem_size);
|
||||
|
||||
list->size++;
|
||||
return (unsigned char *) list + sizeof(list_meta_t);
|
||||
return array;
|
||||
}
|
||||
|
||||
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) {
|
||||
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t));
|
||||
list_meta_t *list = meta(list_ptr);
|
||||
if (n < 0)
|
||||
n = list->size + n;
|
||||
|
||||
@ -106,6 +110,8 @@ void *list_remove(void *list_ptr, int n) {
|
||||
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);
|
||||
|
||||
memset(array + list->size * list->elem_size, 0, list->elem_size);
|
||||
|
||||
list->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) {
|
||||
@ -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) {
|
||||
@ -126,14 +132,13 @@ void *list_delete(void *list_ptr, void *elem) {
|
||||
}
|
||||
|
||||
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;
|
||||
memset(list_ptr, 0, list->max_size * list->elem_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) {
|
||||
list_meta_t *list = (void *) ((unsigned char *) list_ptr - sizeof(list_meta_t));
|
||||
free(list);
|
||||
free(meta(list_ptr));
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu
|
||||
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) {
|
||||
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) {
|
||||
@ -477,6 +477,7 @@ int proxy_init(proxy_ctx_t **proxy_ptr, http_req *req, http_res *res, http_statu
|
||||
retry = tries < 4;
|
||||
goto proxy_err;
|
||||
}
|
||||
buffer[ret] = 0;
|
||||
|
||||
char *buf = buffer;
|
||||
unsigned short header_len = (unsigned short) (strstr(buffer, "\r\n\r\n") - buffer + 4);
|
||||
|
56
src/server.c
56
src/server.c
@ -79,15 +79,18 @@ static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) {
|
||||
}
|
||||
|
||||
void server_free_client(client_ctx_t *ctx) {
|
||||
for (int i = 0; i < list_size(clients); i++) {
|
||||
if (clients[i] == ctx) {
|
||||
clients = list_remove(clients, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
clients = list_delete(clients, &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) {
|
||||
int i = (int) (((int *) arg) - sockets);
|
||||
int fd = sockets[i];
|
||||
@ -98,14 +101,6 @@ static void accept_cb(void *arg) {
|
||||
errno = 0;
|
||||
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;
|
||||
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_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);
|
||||
}
|
||||
|
||||
@ -160,9 +162,9 @@ static void terminate_gracefully(int sig) {
|
||||
workers_stop();
|
||||
workers_destroy();
|
||||
|
||||
for (int i = 0; i < list_size(clients); i++) {
|
||||
tcp_close(clients[i]);
|
||||
}
|
||||
while (list_size(clients) > 0)
|
||||
server_free_client(clients[0]);
|
||||
|
||||
proxy_close_all();
|
||||
logger_set_prefix("");
|
||||
|
||||
@ -177,11 +179,6 @@ int main(int argc, char *const argv[]) {
|
||||
int mode = 0;
|
||||
|
||||
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] = {
|
||||
{.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) {
|
||||
critical("Unable to initialize async thread");
|
||||
ssl_free();
|
||||
geoip_free();
|
||||
list_free(clients);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (proxy_preload() != 0) {
|
||||
critical("Unable to initialize proxy");
|
||||
ssl_free();
|
||||
geoip_free();
|
||||
list_free(clients);
|
||||
async_free();
|
||||
return 1;
|
||||
}
|
||||
@ -325,7 +333,10 @@ int main(int argc, char *const argv[]) {
|
||||
for (int i = 0; i < NUM_SOCKETS; i++) {
|
||||
if (listen(sockets[i], LISTEN_BACKLOG) < 0) {
|
||||
critical("Unable to listen on socket %i", i);
|
||||
ssl_free();
|
||||
geoip_free();
|
||||
list_free(clients);
|
||||
async_free();
|
||||
proxy_unload();
|
||||
return 1;
|
||||
}
|
||||
@ -347,6 +358,7 @@ int main(int argc, char *const argv[]) {
|
||||
notice("Goodbye!");
|
||||
|
||||
// cleanup
|
||||
ssl_free();
|
||||
list_free(clients);
|
||||
geoip_free();
|
||||
proxy_unload();
|
||||
|
@ -29,12 +29,14 @@ void proxy_handler_func(client_ctx_t *ctx) {
|
||||
|
||||
if (ret == 1) {
|
||||
proxy_unlock_ctx(ctx->proxy);
|
||||
ctx->proxy->client = NULL;
|
||||
ctx->proxy = NULL;
|
||||
} else if (ctx->use_proxy == 0) {
|
||||
proxy_close(ctx->proxy);
|
||||
} else if (ctx->use_proxy == 1) {
|
||||
proxy_handler_2(ctx);
|
||||
proxy_unlock_ctx(ctx->proxy);
|
||||
ctx->proxy->client = NULL;
|
||||
ctx->proxy = NULL;
|
||||
} else if (ctx->use_proxy == 2) {
|
||||
// WebSocket
|
||||
|
Reference in New Issue
Block a user