pool: Fix (known) memory leak when querying leases
This commit is contained in:
+38
-21
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2011-2016 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
#include <collections/array.h>
|
||||||
#include <networking/host.h>
|
#include <networking/host.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
#include <attributes/attributes.h>
|
#include <attributes/attributes.h>
|
||||||
@@ -586,11 +588,11 @@ static void resize(char *name, host_t *end)
|
|||||||
/**
|
/**
|
||||||
* create the lease query using the filter string
|
* create the lease query using the filter string
|
||||||
*/
|
*/
|
||||||
static enumerator_t *create_lease_query(char *filter)
|
static enumerator_t *create_lease_query(char *filter, array_t **to_free)
|
||||||
{
|
{
|
||||||
enumerator_t *query;
|
enumerator_t *query;
|
||||||
identification_t *id = NULL;
|
chunk_t id_chunk = chunk_empty, addr_chunk = chunk_empty;
|
||||||
host_t *addr = NULL;
|
id_type_t id_type = 0;
|
||||||
u_int tstamp = 0;
|
u_int tstamp = 0;
|
||||||
bool online = FALSE, valid = FALSE, expired = FALSE;
|
bool online = FALSE, valid = FALSE, expired = FALSE;
|
||||||
char *value, *pos, *pool = NULL;
|
char *value, *pos, *pool = NULL;
|
||||||
@@ -635,18 +637,29 @@ static enumerator_t *create_lease_query(char *filter)
|
|||||||
case FIL_ID:
|
case FIL_ID:
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
identification_t *id;
|
||||||
|
|
||||||
id = identification_create_from_string(value);
|
id = identification_create_from_string(value);
|
||||||
|
id_type = id->get_type(id);
|
||||||
|
id_chunk = chunk_clone(id->get_encoding(id));
|
||||||
|
array_insert_create(to_free, ARRAY_TAIL, id_chunk.ptr);
|
||||||
|
id->destroy(id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIL_ADDR:
|
case FIL_ADDR:
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
host_t *addr;
|
||||||
|
|
||||||
addr = host_create_from_string(value, 0);
|
addr = host_create_from_string(value, 0);
|
||||||
}
|
if (!addr)
|
||||||
if (!addr)
|
{
|
||||||
{
|
fprintf(stderr, "invalid 'addr' in filter string.\n");
|
||||||
fprintf(stderr, "invalid 'addr' in filter string.\n");
|
exit(EXIT_FAILURE);
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
|
addr_chunk = chunk_clone(addr->get_address(addr));
|
||||||
|
array_insert_create(to_free, ARRAY_TAIL, addr_chunk.ptr);
|
||||||
|
addr->destroy(addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIL_TSTAMP:
|
case FIL_TSTAMP:
|
||||||
@@ -710,11 +723,11 @@ static enumerator_t *create_lease_query(char *filter)
|
|||||||
"AND (? OR (identities.type = ? AND identities.data = ?)) "
|
"AND (? OR (identities.type = ? AND identities.data = ?)) "
|
||||||
"AND (? OR address = ?)",
|
"AND (? OR address = ?)",
|
||||||
DB_INT, pool == NULL, DB_TEXT, pool,
|
DB_INT, pool == NULL, DB_TEXT, pool,
|
||||||
DB_INT, id == NULL,
|
DB_INT, !id_chunk.ptr,
|
||||||
DB_INT, id ? id->get_type(id) : 0,
|
DB_INT, id_type,
|
||||||
DB_BLOB, id ? id->get_encoding(id) : chunk_empty,
|
DB_BLOB, id_chunk,
|
||||||
DB_INT, addr == NULL,
|
DB_INT, !addr_chunk.ptr,
|
||||||
DB_BLOB, addr ? addr->get_address(addr) : chunk_empty,
|
DB_BLOB, addr_chunk,
|
||||||
DB_INT, tstamp == 0, DB_UINT, tstamp, DB_UINT, tstamp,
|
DB_INT, tstamp == 0, DB_UINT, tstamp, DB_UINT, tstamp,
|
||||||
DB_INT, !valid, DB_INT, time(NULL),
|
DB_INT, !valid, DB_INT, time(NULL),
|
||||||
DB_INT, !expired, DB_INT, time(NULL),
|
DB_INT, !expired, DB_INT, time(NULL),
|
||||||
@@ -722,14 +735,13 @@ static enumerator_t *create_lease_query(char *filter)
|
|||||||
/* union */
|
/* union */
|
||||||
DB_INT, !(valid || expired),
|
DB_INT, !(valid || expired),
|
||||||
DB_INT, pool == NULL, DB_TEXT, pool,
|
DB_INT, pool == NULL, DB_TEXT, pool,
|
||||||
DB_INT, id == NULL,
|
DB_INT, !id_chunk.ptr,
|
||||||
DB_INT, id ? id->get_type(id) : 0,
|
DB_INT, id_type,
|
||||||
DB_BLOB, id ? id->get_encoding(id) : chunk_empty,
|
DB_BLOB, id_chunk,
|
||||||
DB_INT, addr == NULL,
|
DB_INT, !addr_chunk.ptr,
|
||||||
DB_BLOB, addr ? addr->get_address(addr) : chunk_empty,
|
DB_BLOB, addr_chunk,
|
||||||
/* res */
|
/* res */
|
||||||
DB_TEXT, DB_BLOB, DB_INT, DB_BLOB, DB_UINT, DB_UINT, DB_UINT);
|
DB_TEXT, DB_BLOB, DB_INT, DB_BLOB, DB_UINT, DB_UINT, DB_UINT);
|
||||||
/* id and addr leak but we can't destroy them until query is destroyed. */
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,6 +751,7 @@ static enumerator_t *create_lease_query(char *filter)
|
|||||||
static void leases(char *filter, bool utc)
|
static void leases(char *filter, bool utc)
|
||||||
{
|
{
|
||||||
enumerator_t *query;
|
enumerator_t *query;
|
||||||
|
array_t *to_free = NULL;
|
||||||
chunk_t address_chunk, identity_chunk;
|
chunk_t address_chunk, identity_chunk;
|
||||||
int identity_type;
|
int identity_type;
|
||||||
char *name;
|
char *name;
|
||||||
@@ -748,7 +761,7 @@ static void leases(char *filter, bool utc)
|
|||||||
identification_t *identity;
|
identification_t *identity;
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
|
|
||||||
query = create_lease_query(filter);
|
query = create_lease_query(filter, &to_free);
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "querying leases failed.\n");
|
fprintf(stderr, "querying leases failed.\n");
|
||||||
@@ -809,6 +822,10 @@ static void leases(char *filter, bool utc)
|
|||||||
identity->destroy(identity);
|
identity->destroy(identity);
|
||||||
}
|
}
|
||||||
query->destroy(query);
|
query->destroy(query);
|
||||||
|
if (to_free)
|
||||||
|
{
|
||||||
|
array_destroy_function(to_free, (void*)free, NULL);
|
||||||
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "no matching leases found.\n");
|
fprintf(stderr, "no matching leases found.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user