From 651754834fa0f8fb424843e67948d38c4c11ab6b Mon Sep 17 00:00:00 2001 From: Bin Jin Date: Tue, 23 Nov 2010 14:19:57 +0800 Subject: [PATCH] fix memory leak issues --- http-connect.c | 14 +++++++++++++- http-relay.c | 23 ++++++++++++++++++++--- redsocks.c | 3 +++ redsocks.h | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/http-connect.c b/http-connect.c index e7590a4..33d44a6 100644 --- a/http-connect.c +++ b/http-connect.c @@ -46,6 +46,13 @@ static void httpc_client_init(redsocks_client *client) client->state = httpc_new; } +static void httpc_instance_fini(redsocks_instance *instance) +{ + http_auth *auth = (void*)(instance + 1); + free_null(auth->last_auth_query); + auth->last_auth_query = NULL; +} + static struct evbuffer *httpc_mkconnect(redsocks_client *client); extern const char *auth_request_header; @@ -56,10 +63,13 @@ static char *get_auth_request_header(struct evbuffer *buf) char *line; for (;;) { line = evbuffer_readline(buf); - if (line == NULL || *line == '\0' || strchr(line, ':') == NULL) + if (line == NULL || *line == '\0' || strchr(line, ':') == NULL) { + free_null(line); return NULL; + } if (strncasecmp(line, auth_request_header, strlen(auth_request_header)) == 0) return line; + free(line); } } @@ -99,6 +109,7 @@ static void httpc_read_cb(struct bufferevent *buffev, void *_arg) redsocks_drop_client(client); dropped = 1; } else { + free(line); free_null(auth->last_auth_query); char *ptr = auth_request; @@ -272,6 +283,7 @@ relay_subsys http_connect_subsys = .readcb = httpc_read_cb, .writecb = httpc_write_cb, .init = httpc_client_init, + .instance_fini = httpc_instance_fini, }; /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */ diff --git a/http-relay.c b/http-relay.c index d18fb7a..37dfda4 100644 --- a/http-relay.c +++ b/http-relay.c @@ -98,7 +98,7 @@ static int httpr_buffer_append(httpr_buffer *buff, const char *data, int len) static void httpr_client_init(redsocks_client *client) { - httpr_client *httpr = (void*)(client +1); + httpr_client *httpr = (void*)(client + 1); client->state = httpr_new; memset(httpr, 0, sizeof(*httpr)); @@ -108,21 +108,35 @@ static void httpr_client_init(redsocks_client *client) static void httpr_client_fini(redsocks_client *client) { - httpr_client *httpr = (void*)(client +1); + httpr_client *httpr = (void*)(client + 1); + free_null(httpr->firstline); + httpr->firstline = NULL; + free_null(httpr->host); + httpr->host = NULL; httpr_buffer_fini(&httpr->client_buffer); httpr_buffer_fini(&httpr->relay_buffer); } +static void httpr_instance_fini(redsocks_instance *instance) +{ + http_auth *auth = (void*)(instance + 1); + free_null(auth->last_auth_query); + auth->last_auth_query = NULL; +} + static char *get_auth_request_header(struct evbuffer *buf) { char *line; for (;;) { line = evbuffer_readline(buf); - if (line == NULL || *line == '\0' || strchr(line, ':') == NULL) + if (line == NULL || *line == '\0' || strchr(line, ':') == NULL) { + free_null(line); return NULL; + } if (strncasecmp(line, auth_request_header, strlen(auth_request_header)) == 0) return line; + free(line); } } @@ -136,6 +150,7 @@ static void httpr_relay_read_cb(struct bufferevent *buffev, void *_arg) redsocks_touch_client(client); + httpr_buffer_fini(&httpr->relay_buffer); httpr_buffer_init(&httpr->relay_buffer); if (client->state == httpr_request_sent) { @@ -160,6 +175,7 @@ static void httpr_relay_read_cb(struct bufferevent *buffev, void *_arg) dropped = 1; } else { + free(line); char *auth_request = get_auth_request_header(buffev->input); if (!auth_request) { @@ -584,6 +600,7 @@ relay_subsys http_relay_subsys = .readcb = httpr_relay_read_cb, .writecb = httpr_relay_write_cb, .client_eof = httpr_client_eof, + .instance_fini = httpr_instance_fini, }; /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */ diff --git a/redsocks.c b/redsocks.c index 49814c2..364d8e7 100644 --- a/redsocks.c +++ b/redsocks.c @@ -807,6 +807,9 @@ static void redsocks_fini_instance(redsocks_instance *instance) { } } + if (instance->relay_ss->instance_fini) + instance->relay_ss->instance_fini(instance); + if (event_initialized(&instance->listener)) { if (event_del(&instance->listener) != 0) log_errno(LOG_WARNING, "event_del"); diff --git a/redsocks.h b/redsocks.h index 8e2313c..1a4a7c1 100644 --- a/redsocks.h +++ b/redsocks.h @@ -23,6 +23,7 @@ typedef struct relay_subsys_t { evbuffercb writecb; void (*init)(struct redsocks_client_t *client); void (*fini)(struct redsocks_client_t *client); + void (*instance_fini)(struct redsocks_client_t *client); // connect_relay (if any) is called instead of redsocks_connect_relay after client connection acceptance void (*connect_relay)(struct redsocks_client_t *client); // client_eof is called while relay is not set up but EOF from client is received