Merge branch 'macro_free_v2_squashed'

This commit is contained in:
Nick Mathewson 2017-12-08 14:58:43 -05:00
commit 5ee0cccd49
169 changed files with 975 additions and 554 deletions

8
changes/bug24337 Normal file
View File

@ -0,0 +1,8 @@
o Minor features (defensive programming):
- Most of the functions in Tor that free objects have been replaced
with macros that free the objects and set the corresponding pointers
to NULL. This change should help prevent a large class of dangling
pointer bugs. Closes ticket 24337.
- Where possible, the tor_free() macro now only evaluates its input once.
Part of ticket 24337.

View File

@ -1991,7 +1991,6 @@ if test "x$enable_gcc_warnings_advisory" != "xno"; then
-Winvalid-source-encoding
-Winvalid-token-paste
-Wknr-promoted-parameter
-Wlanguage-extension-token
-Wlarge-by-value-copy
-Wliteral-conversion
-Wliteral-range

View File

@ -346,6 +346,46 @@ macro, as in:
if (BUG(ptr == NULL))
return -1;
Allocator conventions
---------------------
By convention, any tor type with a name like `abc_t` should be allocated
by a function named `abc_new()`. This function should never return
NULL.
Also, a type named `abc_t` should be freed by a function named `abc_free_()`.
Don't call this `abc_free_()` function directly -- instead, wrap it in a
macro called `abc_free()`, using the `FREE_AND_NULL` macro:
void abc_free_(abc_t *obj);
#define abc_free(obj) FREE_AND_NULL(abc_t, abc_free_, (abc))
This macro will free the underlying `abc_t` object, and will also set
the object pointer to NULL.
You should define all `abc_free_()` functions to accept NULL inputs:
void
abc_free_(abc_t *obj)
{
if (!obj)
return;
tor_free(obj->name);
thing_free(obj->thing);
tor_free(obj);
}
If you need a free function that takes a `void *` argument (for example,
to use it as a function callback), define it with a name like
`abc_free_void()`:
static void
abc_free_void_(void *obj)
{
abc_free_(obj);
}
Doxygen comment conventions
---------------------------

View File

@ -1759,14 +1759,14 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
break;
} SMARTLIST_FOREACH_END(a);
free_interface_address6_list(addrs);
interface_address6_list_free(addrs);
return rv;
}
/** Free a smartlist of IP addresses returned by get_interface_address6_list.
*/
void
free_interface_address6_list(smartlist_t *addrs)
interface_address6_list_free_(smartlist_t *addrs)
{
if (addrs != NULL) {
SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
@ -1781,7 +1781,7 @@ free_interface_address6_list(smartlist_t *addrs)
* An empty smartlist means that there are no addresses of the selected type
* matching these criteria.
* Returns NULL on failure.
* Use free_interface_address6_list to free the returned list.
* Use interface_address6_list_free to free the returned list.
*/
MOCK_IMPL(smartlist_t *,
get_interface_address6_list,(int severity,

View File

@ -206,7 +206,9 @@ const char * fmt_addr32(uint32_t addr);
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
tor_addr_t *addr));
void free_interface_address6_list(smartlist_t * addrs);
void interface_address6_list_free_(smartlist_t * addrs);// XXXX
#define interface_address6_list_free(addrs) \
FREE_AND_NULL(smartlist_t, interface_address6_list_free_, (addrs))
MOCK_DECL(smartlist_t *,get_interface_address6_list,(int severity,
sa_family_t family,
int include_internal));
@ -321,13 +323,8 @@ int addr_mask_get_bits(uint32_t mask);
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
/** Free a smartlist of IP addresses returned by get_interface_address_list.
*/
static inline void
free_interface_address_list(smartlist_t *addrs)
{
free_interface_address6_list(addrs);
}
#define interface_address_list_free(lst)\
interface_address6_list_free(lst)
/** Return a smartlist of the IPv4 addresses of all interfaces on the server.
* Excludes loopback and multicast addresses. Only includes internal addresses
* if include_internal is true. (Note that a relay behind NAT may use an

View File

@ -110,7 +110,7 @@ aes_new_cipher(const uint8_t *key, const uint8_t *iv, int key_bits)
return (aes_cnt_cipher_t *) cipher;
}
void
aes_cipher_free(aes_cnt_cipher_t *cipher_)
aes_cipher_free_(aes_cnt_cipher_t *cipher_)
{
if (!cipher_)
return;
@ -324,7 +324,7 @@ aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key, int key_bits)
/** Release storage held by <b>cipher</b>
*/
void
aes_cipher_free(aes_cnt_cipher_t *cipher)
aes_cipher_free_(aes_cnt_cipher_t *cipher)
{
if (!cipher)
return;

View File

@ -17,7 +17,9 @@ typedef struct aes_cnt_cipher aes_cnt_cipher_t;
aes_cnt_cipher_t* aes_new_cipher(const uint8_t *key, const uint8_t *iv,
int key_bits);
void aes_cipher_free(aes_cnt_cipher_t *cipher);
void aes_cipher_free_(aes_cnt_cipher_t *cipher);
#define aes_cipher_free(cipher) \
FREE_AND_NULL(aes_cnt_cipher_t, aes_cipher_free_, (cipher))
void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
int evaluate_evp_for_aes(int force_value);

View File

@ -409,7 +409,7 @@ buf_slack(const buf_t *buf)
/** Release storage held by <b>buf</b>. */
void
buf_free(buf_t *buf)
buf_free_(buf_t *buf)
{
if (!buf)
return;

View File

@ -24,7 +24,8 @@ struct tor_compress_state_t;
buf_t *buf_new(void);
buf_t *buf_new_with_capacity(size_t size);
size_t buf_get_default_chunk_size(const buf_t *buf);
void buf_free(buf_t *buf);
void buf_free_(buf_t *buf);
#define buf_free(b) FREE_AND_NULL(buf_t, buf_free_, (b))
void buf_clear(buf_t *buf);
buf_t *buf_copy(const buf_t *buf);

View File

@ -1905,9 +1905,12 @@ tor_passwd_dup(const struct passwd *pw)
return new_pw;
}
#define tor_passwd_free(pw) \
FREE_AND_NULL(struct passwd, tor_passwd_free_, (pw))
/** Helper: free one of our cached 'struct passwd' values. */
static void
tor_passwd_free(struct passwd *pw)
tor_passwd_free_(struct passwd *pw)
{
if (!pw)
return;

View File

@ -69,7 +69,7 @@ suppress_libevent_log_msg(const char *msg)
/* Wrapper for event_free() that tolerates tor_event_free(NULL) */
void
tor_event_free(struct event *ev)
tor_event_free_(struct event *ev)
{
if (ev == NULL)
return;
@ -213,7 +213,7 @@ periodic_timer_new(struct event_base *base,
/** Stop and free a periodic timer */
void
periodic_timer_free(periodic_timer_t *timer)
periodic_timer_free_(periodic_timer_t *timer)
{
if (!timer)
return;

View File

@ -19,7 +19,9 @@ void suppress_libevent_log_msg(const char *msg);
evdns_add_server_port_with_base(tor_libevent_get_base(), \
(sock),(tcp),(cb),(data));
void tor_event_free(struct event *ev);
void tor_event_free_(struct event *ev);
#define tor_event_free(ev) \
FREE_AND_NULL(struct event, tor_event_free_, (ev))
typedef struct periodic_timer_t periodic_timer_t;
@ -27,7 +29,9 @@ periodic_timer_t *periodic_timer_new(struct event_base *base,
const struct timeval *tv,
void (*cb)(periodic_timer_t *timer, void *data),
void *data);
void periodic_timer_free(periodic_timer_t *);
void periodic_timer_free_(periodic_timer_t *);
#define periodic_timer_free(t) \
FREE_AND_NULL(periodic_timer_t, periodic_timer_free_, (t))
#define tor_event_base_loopexit event_base_loopexit
#define tor_event_base_loopbreak event_base_loopbreak

View File

@ -48,7 +48,7 @@ tor_mutex_new_nonrecursive(void)
}
/** Release all storage and system resources held by <b>m</b>. */
void
tor_mutex_free(tor_mutex_t *m)
tor_mutex_free_(tor_mutex_t *m)
{
if (!m)
return;
@ -68,7 +68,7 @@ tor_cond_new(void)
/** Free all storage held in <b>c</b>. */
void
tor_cond_free(tor_cond_t *c)
tor_cond_free_(tor_cond_t *c)
{
if (!c)
return;

View File

@ -54,7 +54,8 @@ void tor_mutex_init(tor_mutex_t *m);
void tor_mutex_init_nonrecursive(tor_mutex_t *m);
void tor_mutex_acquire(tor_mutex_t *m);
void tor_mutex_release(tor_mutex_t *m);
void tor_mutex_free(tor_mutex_t *m);
void tor_mutex_free_(tor_mutex_t *m);
#define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m))
void tor_mutex_uninit(tor_mutex_t *m);
unsigned long tor_get_thread_id(void);
void tor_threads_init(void);
@ -81,7 +82,8 @@ typedef struct tor_cond_t {
} tor_cond_t;
tor_cond_t *tor_cond_new(void);
void tor_cond_free(tor_cond_t *cond);
void tor_cond_free_(tor_cond_t *cond);
#define tor_cond_free(c) FREE_AND_NULL(tor_cond_t, tor_cond_free_, (c))
int tor_cond_init(tor_cond_t *cond);
void tor_cond_uninit(tor_cond_t *cond);
int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,

View File

@ -598,7 +598,7 @@ tor_compress_process(tor_compress_state_t *state,
/** Deallocate <b>state</b>. */
void
tor_compress_free(tor_compress_state_t *state)
tor_compress_free_(tor_compress_state_t *state)
{
if (state == NULL)
return;

View File

@ -80,7 +80,9 @@ tor_compress_output_t tor_compress_process(tor_compress_state_t *state,
char **out, size_t *out_len,
const char **in, size_t *in_len,
int finish);
void tor_compress_free(tor_compress_state_t *state);
void tor_compress_free_(tor_compress_state_t *state);
#define tor_compress_free(st) \
FREE_AND_NULL(tor_compress_state_t, tor_compress_free_, (st))
size_t tor_compress_state_size(const tor_compress_state_t *state);

View File

@ -323,7 +323,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
/** Deallocate <b>state</b>. */
void
tor_lzma_compress_free(tor_lzma_compress_state_t *state)
tor_lzma_compress_free_(tor_lzma_compress_state_t *state)
{
if (state == NULL)
return;

View File

@ -31,7 +31,10 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
const char **in, size_t *in_len,
int finish);
void tor_lzma_compress_free(tor_lzma_compress_state_t *state);
void tor_lzma_compress_free_(tor_lzma_compress_state_t *state);
#define tor_lzma_compress_free(st) \
FREE_AND_NULL(tor_lzma_compress_state_t, \
tor_lzma_compress_free_, (st))
size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state);

View File

@ -265,7 +265,7 @@ tor_zlib_compress_process(tor_zlib_compress_state_t *state,
/** Deallocate <b>state</b>. */
void
tor_zlib_compress_free(tor_zlib_compress_state_t *state)
tor_zlib_compress_free_(tor_zlib_compress_state_t *state)
{
if (state == NULL)
return;

View File

@ -31,7 +31,10 @@ tor_zlib_compress_process(tor_zlib_compress_state_t *state,
const char **in, size_t *in_len,
int finish);
void tor_zlib_compress_free(tor_zlib_compress_state_t *state);
void tor_zlib_compress_free_(tor_zlib_compress_state_t *state);
#define tor_zlib_compress_free(st) \
FREE_AND_NULL(tor_zlib_compress_state_t, \
tor_zlib_compress_free_, (st))
size_t tor_zlib_compress_state_size(const tor_zlib_compress_state_t *state);

View File

@ -399,7 +399,7 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
/** Deallocate <b>state</b>. */
void
tor_zstd_compress_free(tor_zstd_compress_state_t *state)
tor_zstd_compress_free_(tor_zstd_compress_state_t *state)
{
if (state == NULL)
return;

View File

@ -31,7 +31,10 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
const char **in, size_t *in_len,
int finish);
void tor_zstd_compress_free(tor_zstd_compress_state_t *state);
void tor_zstd_compress_free_(tor_zstd_compress_state_t *state);
#define tor_zstd_compress_free(st) \
FREE_AND_NULL(tor_zstd_compress_state_t, \
tor_zstd_compress_free_, (st))
size_t tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state);

View File

@ -330,7 +330,7 @@ config_process_include(const char *path, int recursion_level, int extended,
* Free all the configuration lines on the linked list <b>front</b>.
*/
void
config_free_lines(config_line_t *front)
config_free_lines_(config_line_t *front)
{
config_line_t *tmp;

View File

@ -48,7 +48,12 @@ int config_get_lines(const char *string, config_line_t **result, int extended);
int config_get_lines_include(const char *string, config_line_t **result,
int extended, int *has_include,
smartlist_t *opened_lst);
void config_free_lines(config_line_t *front);
void config_free_lines_(config_line_t *front);
#define config_free_lines(front) \
do { \
config_free_lines_(front); \
(front) = NULL; \
} while (0)
const char *parse_config_line_from_str_verbose(const char *line,
char **key_out, char **value_out,
const char **err_out);

View File

@ -42,7 +42,7 @@ smartlist_new,(void))
* list's elements.
*/
MOCK_IMPL(void,
smartlist_free,(smartlist_t *sl))
smartlist_free_,(smartlist_t *sl))
{
if (!sl)
return;
@ -1163,19 +1163,26 @@ HT_GENERATE2(digest256map_impl, digest256map_entry_t, node,
digest256map_entry_hash,
digest256map_entries_eq, 0.6, tor_reallocarray_, tor_free_)
#define strmap_entry_free(ent) \
FREE_AND_NULL(strmap_entry_t, strmap_entry_free_, (ent))
#define digestmap_entry_free(ent) \
FREE_AND_NULL(digestmap_entry_t, digestmap_entry_free_, (ent))
#define digest256map_entry_free(ent) \
FREE_AND_NULL(digest256map_entry_t, digest256map_entry_free_, (ent))
static inline void
strmap_entry_free(strmap_entry_t *ent)
strmap_entry_free_(strmap_entry_t *ent)
{
tor_free(ent->key);
tor_free(ent);
}
static inline void
digestmap_entry_free(digestmap_entry_t *ent)
digestmap_entry_free_(digestmap_entry_t *ent)
{
tor_free(ent);
}
static inline void
digest256map_entry_free(digest256map_entry_t *ent)
digest256map_entry_free_(digest256map_entry_t *ent)
{
tor_free(ent);
}
@ -1335,7 +1342,7 @@ digest256map_assign_key(digest256map_entry_t *ent, const uint8_t *key)
* those entries. If free_val is provided, invoked it every value in \
* <b>map</b>. */ \
MOCK_IMPL(void, \
prefix##_free, (maptype *map, void (*free_val)(void*))) \
prefix##_free_, (maptype *map, void (*free_val)(void*))) \
{ \
prefix##_entry_t **ent, **next, *this; \
if (!map) \
@ -1525,7 +1532,7 @@ digestset_new(int max_elements)
/** Free all storage held in <b>set</b>. */
void
digestset_free(digestset_t *set)
digestset_free_(digestset_t *set)
{
if (!set)
return;

View File

@ -28,7 +28,9 @@ typedef struct smartlist_t {
} smartlist_t;
MOCK_DECL(smartlist_t *, smartlist_new, (void));
MOCK_DECL(void, smartlist_free, (smartlist_t *sl));
MOCK_DECL(void, smartlist_free_, (smartlist_t *sl));
#define smartlist_free(sl) FREE_AND_NULL(smartlist_t, smartlist_free_, (sl))
void smartlist_clear(smartlist_t *sl);
void smartlist_add(smartlist_t *sl, void *element);
void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2);
@ -350,7 +352,7 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join,
void* prefix##set(maptype *map, keytype key, void *val); \
void* prefix##get(const maptype *map, keytype key); \
void* prefix##remove(maptype *map, keytype key); \
MOCK_DECL(void, prefix##free, (maptype *map, void (*free_val)(void*))); \
MOCK_DECL(void, prefix##free_, (maptype *map, void (*free_val)(void*))); \
int prefix##isempty(const maptype *map); \
int prefix##size(const maptype *map); \
prefix##iter_t *prefix##iter_init(maptype *map); \
@ -368,6 +370,16 @@ DECLARE_MAP_FNS(digestmap_t, const char *, digestmap_);
* table. */
DECLARE_MAP_FNS(digest256map_t, const uint8_t *, digest256map_);
#define MAP_FREE_AND_NULL(maptype, map, fn) \
do { \
maptype ## _free_((map), (fn)); \
(map) = NULL; \
} while (0)
#define strmap_free(map, fn) MAP_FREE_AND_NULL(strmap, (map), (fn))
#define digestmap_free(map, fn) MAP_FREE_AND_NULL(digestmap, (map), (fn))
#define digest256map_free(map, fn) MAP_FREE_AND_NULL(digest256map, (map), (fn))
#undef DECLARE_MAP_FNS
/** Iterates over the key-value pairs in a map <b>map</b> in order.
@ -528,9 +540,9 @@ void* strmap_remove_lc(strmap_t *map, const char *key);
return (valtype*)digestmap_remove((digestmap_t*)map, key); \
} \
ATTR_UNUSED static inline void \
prefix##f##ree(maptype *map, void (*free_val)(void*)) \
prefix##f##ree_(maptype *map, void (*free_val)(void*)) \
{ \
digestmap_free((digestmap_t*)map, free_val); \
digestmap_free_((digestmap_t*)map, free_val); \
} \
ATTR_UNUSED static inline int \
prefix##isempty(maptype *map) \
@ -614,10 +626,12 @@ bitarray_expand(bitarray_t *ba,
}
/** Free the bit array <b>ba</b>. */
static inline void
bitarray_free(bitarray_t *ba)
bitarray_free_(bitarray_t *ba)
{
tor_free(ba);
}
#define bitarray_free(ba) FREE_AND_NULL(bitarray_t, bitarray_free_, (ba))
/** Set the <b>bit</b>th bit in <b>b</b> to 1. */
static inline void
bitarray_set(bitarray_t *b, int bit)
@ -679,7 +693,8 @@ digestset_contains(const digestset_t *set, const char *digest)
#undef BIT
digestset_t *digestset_new(int max_elements);
void digestset_free(digestset_t* set);
void digestset_free_(digestset_t* set);
#define digestset_free(set) FREE_AND_NULL(digestset_t, digestset_free_, (set))
/* These functions, given an <b>array</b> of <b>n_elements</b>, return the
* <b>nth</b> lowest element. <b>nth</b>=0 gives the lowest element;

View File

@ -529,7 +529,7 @@ crypto_pk_new,(void))
* are released, free the key.
*/
void
crypto_pk_free(crypto_pk_t *env)
crypto_pk_free_(crypto_pk_t *env)
{
if (!env)
return;
@ -592,7 +592,7 @@ crypto_cipher_new(const char *key)
/** Free a symmetric cipher.
*/
void
crypto_cipher_free(crypto_cipher_t *env)
crypto_cipher_free_(crypto_cipher_t *env)
{
if (!env)
return;
@ -1977,7 +1977,7 @@ crypto_digest512_new(digest_algorithm_t algorithm)
/** Deallocate a digest object.
*/
void
crypto_digest_free(crypto_digest_t *digest)
crypto_digest_free_(crypto_digest_t *digest)
{
if (!digest)
return;
@ -2224,7 +2224,7 @@ crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len)
/** Cleanse and deallocate a XOF object. */
void
crypto_xof_free(crypto_xof_t *xof)
crypto_xof_free_(crypto_xof_t *xof)
{
if (!xof)
return;
@ -2777,7 +2777,7 @@ crypto_expand_key_material_rfc5869_sha256(
/** Free a DH key exchange object.
*/
void
crypto_dh_free(crypto_dh_t *dh)
crypto_dh_free_(crypto_dh_t *dh)
{
if (!dh)
return;

View File

@ -19,6 +19,7 @@
#include "torint.h"
#include "testsupport.h"
#include "compat.h"
#include "util.h"
#include <openssl/engine.h>
#include "keccak-tiny/keccak-tiny.h"
@ -146,7 +147,8 @@ int crypto_global_cleanup(void);
/* environment setup */
MOCK_DECL(crypto_pk_t *,crypto_pk_new,(void));
void crypto_pk_free(crypto_pk_t *env);
void crypto_pk_free_(crypto_pk_t *env);
#define crypto_pk_free(pk) FREE_AND_NULL(crypto_pk_t, crypto_pk_free_, (pk))
void crypto_set_tls_dh_prime(void);
crypto_cipher_t *crypto_cipher_new(const char *key);
@ -155,7 +157,9 @@ crypto_cipher_t *crypto_cipher_new_with_iv(const char *key, const char *iv);
crypto_cipher_t *crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
const uint8_t *iv,
int bits);
void crypto_cipher_free(crypto_cipher_t *env);
void crypto_cipher_free_(crypto_cipher_t *env);
#define crypto_cipher_free(c) \
FREE_AND_NULL(crypto_cipher_t, crypto_cipher_free_, (c))
/* public key crypto */
MOCK_DECL(int, crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits));
@ -258,7 +262,9 @@ int crypto_digest_algorithm_parse_name(const char *name);
crypto_digest_t *crypto_digest_new(void);
crypto_digest_t *crypto_digest256_new(digest_algorithm_t algorithm);
crypto_digest_t *crypto_digest512_new(digest_algorithm_t algorithm);
void crypto_digest_free(crypto_digest_t *digest);
void crypto_digest_free_(crypto_digest_t *digest);
#define crypto_digest_free(d) \
FREE_AND_NULL(crypto_digest_t, crypto_digest_free_, (d))
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
size_t len);
void crypto_digest_get_digest(crypto_digest_t *digest,
@ -276,7 +282,9 @@ void crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out,
crypto_xof_t *crypto_xof_new(void);
void crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len);
void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len);
void crypto_xof_free(crypto_xof_t *xof);
void crypto_xof_free_(crypto_xof_t *xof);
#define crypto_xof_free(xof) \
FREE_AND_NULL(crypto_xof_t, crypto_xof_free_, (xof))
/* Key negotiation */
#define DH_TYPE_CIRCUIT 1
@ -291,7 +299,8 @@ int crypto_dh_get_public(crypto_dh_t *dh, char *pubkey_out,
ssize_t crypto_dh_compute_secret(int severity, crypto_dh_t *dh,
const char *pubkey, size_t pubkey_len,
char *secret_out, size_t secret_out_len);
void crypto_dh_free(crypto_dh_t *dh);
void crypto_dh_free_(crypto_dh_t *dh);
#define crypto_dh_free(dh) FREE_AND_NULL(crypto_dh_t, crypto_dh_free_, (dh))
int crypto_expand_key_material_TAP(const uint8_t *key_in,
size_t key_in_len,

View File

@ -622,7 +622,7 @@ ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
/** Release all storage held for <b>kp</b>. */
void
ed25519_keypair_free(ed25519_keypair_t *kp)
ed25519_keypair_free_(ed25519_keypair_t *kp)
{
if (! kp)
return;

View File

@ -7,6 +7,7 @@
#include "testsupport.h"
#include "torint.h"
#include "crypto_curve25519.h"
#include "util.h"
#define ED25519_PUBKEY_LEN 32
#define ED25519_SECKEY_LEN 64
@ -117,7 +118,9 @@ int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
char **tag_out,
const char *filename);
void ed25519_keypair_free(ed25519_keypair_t *kp);
void ed25519_keypair_free_(ed25519_keypair_t *kp);
#define ed25519_keypair_free(kp) \
FREE_AND_NULL(ed25519_keypair_t, ed25519_keypair_free_, (kp))
int ed25519_pubkey_eq(const ed25519_public_key_t *key1,
const ed25519_public_key_t *key2);

View File

@ -148,7 +148,7 @@ struct di_digest256_map_t {
/** Release all storage held in <b>map</b>, calling free_fn on each value
* as we go. */
void
dimap_free(di_digest256_map_t *map, dimap_free_fn free_fn)
dimap_free_(di_digest256_map_t *map, dimap_free_fn free_fn)
{
while (map) {
di_digest256_map_t *victim = map;

View File

@ -37,7 +37,12 @@ int safe_mem_is_zero(const void *mem, size_t sz);
typedef struct di_digest256_map_t di_digest256_map_t;
typedef void (*dimap_free_fn)(void *);
void dimap_free(di_digest256_map_t *map, dimap_free_fn free_fn);
void dimap_free_(di_digest256_map_t *map, dimap_free_fn free_fn);
#define dimap_free(map, free_fn) \
do { \
dimap_free_((map), (free_fn)); \
(map) = NULL; \
} while (0)
void dimap_add_entry(di_digest256_map_t **map,
const uint8_t *key, void *val);
void *dimap_search(const di_digest256_map_t *map, const uint8_t *key,

View File

@ -59,7 +59,7 @@
#define HANDLE_DECL(name, structname, linkage) \
typedef struct name ## _handle_t name ## _handle_t; \
linkage name ## _handle_t *name ## _handle_new(struct structname *object); \
linkage void name ## _handle_free(name ## _handle_t *); \
linkage void name ## _handle_free_(name ## _handle_t *); \
linkage struct structname *name ## _handle_get(name ## _handle_t *); \
linkage void name ## _handles_clear(struct structname *object);
@ -113,7 +113,7 @@
} \
\
linkage void \
name ## _handle_free(struct name ## _handle_t *ref) \
name ## _handle_free_(struct name ## _handle_t *ref) \
{ \
if (! ref) return; \
name ## _handle_head_t *head = ref->head; \

View File

@ -63,7 +63,9 @@ typedef struct logfile_t {
* log for each log domain? */
} logfile_t;
static void log_free(logfile_t *victim);
static void log_free_(logfile_t *victim);
#define log_free(lg) \
FREE_AND_NULL(logfile_t, log_free_, (lg))
/** Helper: map a log severity to descriptive string. */
static inline const char *
@ -385,9 +387,12 @@ pending_log_message_new(int severity, log_domain_mask_t domain,
return m;
}
#define pending_log_message_free(msg) \
FREE_AND_NULL(pending_log_message_t, pending_log_message_free_, (msg))
/** Release all storage held by <b>msg</b>. */
static void
pending_log_message_free(pending_log_message_t *msg)
pending_log_message_free_(pending_log_message_t *msg)
{
if (!msg)
return;
@ -721,7 +726,7 @@ log_fn_ratelim_(ratelim_t *ratelim, int severity, log_domain_mask_t domain,
/** Free all storage held by <b>victim</b>. */
static void
log_free(logfile_t *victim)
log_free_(logfile_t *victim)
{
if (!victim)
return;

View File

@ -153,7 +153,7 @@ memarea_new(void)
/** Free <b>area</b>, invalidating all pointers returned from memarea_alloc()
* and friends for this area */
void
memarea_drop_all(memarea_t *area)
memarea_drop_all_(memarea_t *area)
{
memarea_chunk_t *chunk, *next;
for (chunk = area->first; chunk; chunk = next) {

View File

@ -8,7 +8,12 @@
typedef struct memarea_t memarea_t;
memarea_t *memarea_new(void);
void memarea_drop_all(memarea_t *area);
void memarea_drop_all_(memarea_t *area);
#define memarea_drop_all(area) \
do { \
memarea_drop_all_(area); \
(area) = NULL; \
} while (0)
void memarea_clear(memarea_t *area);
int memarea_owns_ptr(const memarea_t *area, const void *ptr);
void *memarea_alloc(memarea_t *area, size_t sz);

View File

@ -325,7 +325,7 @@ tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2,
/** Free the process-termination monitor <b>procmon</b>. */
void
tor_process_monitor_free(tor_process_monitor_t *procmon)
tor_process_monitor_free_(tor_process_monitor_t *procmon)
{
if (procmon == NULL)
return;

View File

@ -27,7 +27,9 @@ tor_process_monitor_t *tor_process_monitor_new(struct event_base *base,
tor_procmon_callback_t cb,
void *cb_arg,
const char **msg);
void tor_process_monitor_free(tor_process_monitor_t *procmon);
void tor_process_monitor_free_(tor_process_monitor_t *procmon);
#define tor_process_monitor_free(procmon) \
FREE_AND_NULL(tor_process_monitor_t, tor_process_monitor_free_, (procmon))
#endif /* !defined(TOR_PROCMON_H) */

View File

@ -1521,8 +1521,12 @@ cached_getaddrinfo_items_eq(const cached_getaddrinfo_item_t *a,
return (a->family == b->family) && 0 == strcmp(a->name, b->name);
}
#define cached_getaddrinfo_item_free(item) \
FREE_AND_NULL(cached_getaddrinfo_item_t, \
cached_getaddrinfo_item_free_, (item))
static void
cached_getaddrinfo_item_free(cached_getaddrinfo_item_t *item)
cached_getaddrinfo_item_free_(cached_getaddrinfo_item_t *item)
{
if (item == NULL)
return;

View File

@ -59,7 +59,7 @@ storage_dir_new(const char *dirname, int max_files)
* Drop all in-RAM storage for <b>d</b>. Does not delete any files.
*/
void
storage_dir_free(storage_dir_t *d)
storage_dir_free_(storage_dir_t *d)
{
if (d == NULL)
return;

View File

@ -9,7 +9,10 @@ struct config_line_t;
struct sandbox_cfg_elem;
storage_dir_t * storage_dir_new(const char *dirname, int n_files);
void storage_dir_free(storage_dir_t *d);
void storage_dir_free_(storage_dir_t *d);
#define storage_dir_free(d) \
FREE_AND_NULL(storage_dir_t, storage_dir_free_, (d))
int storage_dir_register_with_sandbox(storage_dir_t *d,
struct sandbox_cfg_elem **cfg);
const smartlist_t *storage_dir_list(storage_dir_t *d);

View File

@ -245,7 +245,7 @@ timer_new(timer_cb_fn_t cb, void *arg)
* scheduled.
*/
void
timer_free(tor_timer_t *t)
timer_free_(tor_timer_t *t)
{
if (! t)
return;

View File

@ -17,7 +17,8 @@ void timer_get_cb(const tor_timer_t *t,
timer_cb_fn_t *cb_out, void **arg_out);
void timer_schedule(tor_timer_t *t, const struct timeval *delay);
void timer_disable(tor_timer_t *t);
void timer_free(tor_timer_t *t);
void timer_free_(tor_timer_t *t);
#define timer_free(t) FREE_AND_NULL(tor_timer_t, timer_free_, (t))
void timers_initialize(void);
void timers_shutdown(void);

View File

@ -644,7 +644,7 @@ static const char CLIENT_CIPHER_LIST[] =
/** Free all storage held in <b>cert</b> */
void
tor_x509_cert_free(tor_x509_cert_t *cert)
tor_x509_cert_free_(tor_x509_cert_t *cert)
{
if (! cert)
return;
@ -1792,7 +1792,7 @@ tor_tls_is_server(tor_tls_t *tls)
* underlying file descriptor.
*/
void
tor_tls_free(tor_tls_t *tls)
tor_tls_free_(tor_tls_t *tls)
{
if (!tls)
return;

View File

@ -216,7 +216,8 @@ void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
void (*cb)(tor_tls_t *, void *arg),
void *arg);
int tor_tls_is_server(tor_tls_t *tls);
void tor_tls_free(tor_tls_t *tls);
void tor_tls_free_(tor_tls_t *tls);
#define tor_tls_free(tls) FREE_AND_NULL(tor_tls_t, tor_tls_free_, (tls))
int tor_tls_peer_has_cert(tor_tls_t *tls);
MOCK_DECL(tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls));
MOCK_DECL(tor_x509_cert_t *,tor_tls_get_own_cert,(tor_tls_t *tls));
@ -263,7 +264,9 @@ void check_no_tls_errors_(const char *fname, int line);
void tor_tls_log_one_error(tor_tls_t *tls, unsigned long err,
int severity, int domain, const char *doing);
void tor_x509_cert_free(tor_x509_cert_t *cert);
void tor_x509_cert_free_(tor_x509_cert_t *cert);
#define tor_x509_cert_free(c) \
FREE_AND_NULL(tor_x509_cert_t, tor_x509_cert_free_, (c))
tor_x509_cert_t *tor_x509_cert_decode(const uint8_t *certificate,
size_t certificate_len);
void tor_x509_cert_get_der(const tor_x509_cert_t *cert,

View File

@ -4713,7 +4713,7 @@ environment_variable_names_equal(const char *s1, const char *s2)
/** Free <b>env</b> (assuming it was produced by
* process_environment_make). */
void
process_environment_free(process_environment_t *env)
process_environment_free_(process_environment_t *env)
{
if (env == NULL) return;

View File

@ -80,12 +80,22 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
* This is a macro. If you need a function pointer to release memory from
* tor_malloc(), use tor_free_().
*/
#ifdef __GNUC__
#define tor_free(p) STMT_BEGIN \
typeof(&(p)) tor_free__tmpvar = &(p); \
if (PREDICT_LIKELY((*tor_free__tmpvar)!=NULL)) { \
raw_free(*tor_free__tmpvar); \
*tor_free__tmpvar=NULL; \
} \
STMT_END
#else
#define tor_free(p) STMT_BEGIN \
if (PREDICT_LIKELY((p)!=NULL)) { \
raw_free(p); \
(p)=NULL; \
} \
STMT_END
#endif
#endif /* defined(USE_DMALLOC) */
#define tor_malloc(size) tor_malloc_(size DMALLOC_ARGS)
@ -109,6 +119,17 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
void tor_log_mallinfo(int severity);
/* Helper macro: free a variable of type 'typename' using freefn, and
* set the variable to NULL.
*/
#define FREE_AND_NULL(typename, freefn, var) \
do { \
/* only evaluate (var) once. */ \
typename **tmp__free__ptr ## freefn = &(var); \
freefn(*tmp__free__ptr ## freefn); \
(*tmp__free__ptr ## freefn) = NULL; \
} while (0)
/** Macro: yield a pointer to the field at position <b>off</b> within the
* structure <b>st</b>. Example:
* <pre>
@ -423,7 +444,9 @@ struct process_environment_t {
};
process_environment_t *process_environment_make(struct smartlist_t *env_vars);
void process_environment_free(process_environment_t *env);
void process_environment_free_(process_environment_t *env);
#define process_environment_free(env) \
FREE_AND_NULL(process_environment_t, process_environment_free_, (env))
struct smartlist_t *get_current_process_environment_variables(void);

View File

@ -148,12 +148,15 @@ workqueue_entry_new(workqueue_reply_t (*fn)(void*, void*),
return ent;
}
#define workqueue_entry_free(ent) \
FREE_AND_NULL(workqueue_entry_t, workqueue_entry_free_, (ent))
/**
* Release all storage held in <b>ent</b>. Call only when <b>ent</b> is not on
* any queue.
*/
static void
workqueue_entry_free(workqueue_entry_t *ent)
workqueue_entry_free_(workqueue_entry_t *ent)
{
if (!ent)
return;

View File

@ -90,34 +90,47 @@ addressmap_init(void)
virtaddress_reversemap = strmap_new();
}
#define addressmap_ent_free(ent) \
FREE_AND_NULL(addressmap_entry_t, addressmap_ent_free_, (ent))
/** Free the memory associated with the addressmap entry <b>_ent</b>. */
static void
addressmap_ent_free(void *_ent)
addressmap_ent_free_(addressmap_entry_t *ent)
{
addressmap_entry_t *ent;
if (!_ent)
if (!ent)
return;
ent = _ent;
tor_free(ent->new_address);
tor_free(ent);
}
static void
addressmap_ent_free_void(void *ent)
{
addressmap_ent_free_(ent);
}
#define addressmap_virtaddress_ent_free(ent) \
FREE_AND_NULL(virtaddress_entry_t, addressmap_virtaddress_ent_free_, (ent))
/** Free storage held by a virtaddress_entry_t* entry in <b>_ent</b>. */
static void
addressmap_virtaddress_ent_free(void *_ent)
addressmap_virtaddress_ent_free_(virtaddress_entry_t *ent)
{
virtaddress_entry_t *ent;
if (!_ent)
if (!ent)
return;
ent = _ent;
tor_free(ent->ipv4_address);
tor_free(ent->ipv6_address);
tor_free(ent->hostname_address);
tor_free(ent);
}
static void
addressmap_virtaddress_ent_free_void(void *ent)
{
addressmap_virtaddress_ent_free_(ent);
}
/** Remove <b>address</b> (which must map to <b>ent</b>) from the
* virtual address map. */
static void
@ -311,10 +324,10 @@ addressmap_clean(time_t now)
void
addressmap_free_all(void)
{
strmap_free(addressmap, addressmap_ent_free);
strmap_free(addressmap, addressmap_ent_free_void);
addressmap = NULL;
strmap_free(virtaddress_reversemap, addressmap_virtaddress_ent_free);
strmap_free(virtaddress_reversemap, addressmap_virtaddress_ent_free_void);
virtaddress_reversemap = NULL;
}

View File

@ -53,7 +53,10 @@ struct bridge_info_t {
smartlist_t *socks_args;
};
static void bridge_free(bridge_info_t *bridge);
#define bridge_free(bridge) \
FREE_AND_NULL(bridge_info_t, bridge_free_, (bridge))
static void bridge_free_(bridge_info_t *bridge);
static void rewrite_node_address_for_bridge(const bridge_info_t *bridge,
node_t *node);
@ -101,7 +104,7 @@ clear_bridge_list(void)
/** Free the bridge <b>bridge</b>. */
static void
bridge_free(bridge_info_t *bridge)
bridge_free_(bridge_info_t *bridge)
{
if (!bridge)
return;

View File

@ -1,3 +1,4 @@
/* * Copyright (c) 2012-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
@ -162,12 +163,12 @@ HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
/* Functions to maintain the digest map */
static void channel_remove_from_digest_map(channel_t *chan);
static void channel_force_free(channel_t *chan);
static void
channel_free_list(smartlist_t *channels, int mark_for_close);
static void
channel_listener_free_list(smartlist_t *channels, int mark_for_close);
static void channel_listener_force_free(channel_listener_t *chan_l);
static void channel_force_xfree(channel_t *chan);
static void channel_free_list(smartlist_t *channels,
int mark_for_close);
static void channel_listener_free_list(smartlist_t *channels,
int mark_for_close);
static void channel_listener_force_xfree(channel_listener_t *chan_l);
/***********************************
* Channel state utility functions *
@ -881,7 +882,7 @@ channel_init_listener(channel_listener_t *chan_l)
*/
void
channel_free(channel_t *chan)
channel_free_(channel_t *chan)
{
if (!chan) return;
@ -934,7 +935,7 @@ channel_free(channel_t *chan)
*/
void
channel_listener_free(channel_listener_t *chan_l)
channel_listener_free_(channel_listener_t *chan_l)
{
if (!chan_l) return;
@ -962,7 +963,7 @@ channel_listener_free(channel_listener_t *chan_l)
*/
static void
channel_force_free(channel_t *chan)
channel_force_xfree(channel_t *chan)
{
tor_assert(chan);
@ -1007,7 +1008,7 @@ channel_force_free(channel_t *chan)
*/
static void
channel_listener_force_free(channel_listener_t *chan_l)
channel_listener_force_xfree(channel_listener_t *chan_l)
{
tor_assert(chan_l);
@ -1431,7 +1432,6 @@ channel_clear_remote_end(channel_t *chan)
/**
* Write to a channel the given packed cell.
*
* Return 0 on success or -1 on error.
*
* Two possible errors can happen. Either the channel is not opened or the
* lower layer (specialized channel) failed to write it. In both cases, it is
@ -2239,7 +2239,7 @@ channel_free_list(smartlist_t *channels, int mark_for_close)
if (!CHANNEL_CONDEMNED(curr)) {
channel_mark_for_close(curr);
}
channel_force_free(curr);
channel_force_xfree(curr);
} else channel_free(curr);
} SMARTLIST_FOREACH_END(curr);
}
@ -2268,7 +2268,7 @@ channel_listener_free_list(smartlist_t *listeners, int mark_for_close)
curr->state == CHANNEL_LISTENER_STATE_ERROR)) {
channel_listener_mark_for_close(curr);
}
channel_listener_force_free(curr);
channel_listener_force_xfree(curr);
} else channel_listener_free(curr);
} SMARTLIST_FOREACH_END(curr);
}

View File

@ -458,8 +458,11 @@ void channel_close_for_error(channel_t *chan);
void channel_closed(channel_t *chan);
/* Free a channel */
void channel_free(channel_t *chan);
void channel_listener_free(channel_listener_t *chan_l);
void channel_free_(channel_t *chan);
#define channel_free(chan) FREE_AND_NULL(channel_t, channel_free_, (chan))
void channel_listener_free_(channel_listener_t *chan_l);
#define channel_listener_free(chan_l) \
FREE_AND_NULL(channel_listener_t, channel_listener_free_, (chan_l))
/* State/metadata setters */
@ -634,6 +637,8 @@ int packed_cell_is_destroy(channel_t *chan,
/* Declare the handle helpers */
HANDLE_DECL(channel, channel_s,)
#define channel_handle_free(h) \
FREE_AND_NULL(channel_handle_t, channel_handle_free_, (h))
#endif /* !defined(TOR_CHANNEL_H) */

View File

@ -2732,7 +2732,7 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
/** Release storage held by an extend_info_t struct. */
void
extend_info_free(extend_info_t *info)
extend_info_free_(extend_info_t *info)
{
if (!info)
return;

View File

@ -58,7 +58,9 @@ extend_info_t *extend_info_new(const char *nickname,
const tor_addr_t *addr, uint16_t port);
extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
extend_info_t *extend_info_dup(extend_info_t *info);
void extend_info_free(extend_info_t *info);
void extend_info_free_(extend_info_t *info);
#define extend_info_free(info) \
FREE_AND_NULL(extend_info_t, extend_info_free_, (info))
int extend_info_addr_is_allowed(const tor_addr_t *addr);
int extend_info_supports_tap(const extend_info_t* ei);
int extend_info_supports_ntor(const extend_info_t* ei);

View File

@ -923,7 +923,7 @@ circuit_clear_testing_cell_stats(circuit_t *circ)
/** Deallocate space associated with circ.
*/
STATIC void
circuit_free(circuit_t *circ)
circuit_free_(circuit_t *circ)
{
circid_t n_circ_id = 0;
void *mem;
@ -1086,7 +1086,7 @@ circuit_free_all(void)
while (or_circ->resolving_streams) {
edge_connection_t *next_conn;
next_conn = or_circ->resolving_streams->next_stream;
connection_free(TO_CONN(or_circ->resolving_streams));
connection_free_(TO_CONN(or_circ->resolving_streams));
or_circ->resolving_streams = next_conn;
}
}

View File

@ -81,7 +81,8 @@ MOCK_DECL(void, channel_note_destroy_not_pending,
smartlist_t *circuit_find_circuits_to_upgrade_from_guard_wait(void);
#ifdef CIRCUITLIST_PRIVATE
STATIC void circuit_free(circuit_t *circ);
STATIC void circuit_free_(circuit_t *circ);
#define circuit_free(circ) FREE_AND_NULL(circuit_t, circuit_free_, (circ))
STATIC size_t n_cells_in_circ_queues(const circuit_t *c);
STATIC uint32_t circuit_max_queued_data_age(const circuit_t *c, uint32_t now);
STATIC uint32_t circuit_max_queued_cell_age(const circuit_t *c, uint32_t now);

View File

@ -546,7 +546,7 @@ circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux, channel_t *chan)
*/
void
circuitmux_free(circuitmux_t *cmux)
circuitmux_free_(circuitmux_t *cmux)
{
if (!cmux) return;

View File

@ -104,7 +104,9 @@ void circuitmux_assert_okay(circuitmux_t *cmux);
circuitmux_t * circuitmux_alloc(void);
void circuitmux_detach_all_circuits(circuitmux_t *cmux,
smartlist_t *detached_out);
void circuitmux_free(circuitmux_t *cmux);
void circuitmux_free_(circuitmux_t *cmux);
#define circuitmux_free(cmux) \
FREE_AND_NULL(circuitmux_t, circuitmux_free_, (cmux))
/* Policy control */
void circuitmux_clear_policy(circuitmux_t *cmux);

View File

@ -782,7 +782,7 @@ static or_options_t *global_default_options = NULL;
/** Name of most recently read torrc file. */
static char *torrc_fname = NULL;
/** Name of the most recently read torrc-defaults file.*/
static char *torrc_defaults_fname;
static char *torrc_defaults_fname = NULL;
/** Configuration options set by command line. */
static config_line_t *global_cmdline_options = NULL;
/** Non-configuration options set by the command line */
@ -926,7 +926,7 @@ get_short_version(void)
/** Release additional memory allocated in options
*/
STATIC void
or_options_free(or_options_t *options)
or_options_free_(or_options_t *options)
{
if (!options)
return;
@ -984,6 +984,8 @@ config_free_all(void)
tor_free(the_short_tor_version);
tor_free(the_tor_version);
have_parsed_cmdline = 0;
}
/** Make <b>address</b> -- a piece of information related to our operation as
@ -5825,7 +5827,7 @@ validate_transport_socks_arguments(const smartlist_t *args)
/** Deallocate a bridge_line_t structure. */
/* private */ void
bridge_line_free(bridge_line_t *bridge_line)
bridge_line_free_(bridge_line_t *bridge_line)
{
if (!bridge_line)
return;
@ -6591,7 +6593,7 @@ port_cfg_new(size_t namelen)
/** Free all storage held in <b>port</b> */
STATIC void
port_cfg_free(port_cfg_t *port)
port_cfg_free_(port_cfg_t *port)
{
tor_free(port);
}

View File

@ -198,7 +198,9 @@ typedef struct bridge_line_t {
transport proxy. */
} bridge_line_t;
void bridge_line_free(bridge_line_t *bridge_line);
void bridge_line_free_(bridge_line_t *bridge_line);
#define bridge_line_free(line) \
FREE_AND_NULL(bridge_line_t, bridge_line_free_, (line))
bridge_line_t *parse_bridge_line(const char *line);
smartlist_t *get_options_from_transport_options_line(const char *line,
const char *transport);
@ -221,8 +223,12 @@ extern struct config_format_t options_format;
#endif
STATIC port_cfg_t *port_cfg_new(size_t namelen);
STATIC void port_cfg_free(port_cfg_t *port);
STATIC void or_options_free(or_options_t *options);
#define port_cfg_free(port) \
FREE_AND_NULL(port_cfg_t, port_cfg_free_, (port))
STATIC void port_cfg_free_(port_cfg_t *port);
#define or_options_free(opt) \
FREE_AND_NULL(or_options_t, or_options_free_, (opt))
STATIC void or_options_free_(or_options_t *options);
STATIC int options_validate_single_onion(or_options_t *options,
char **msg);
STATIC int options_validate(or_options_t *old_options,

View File

@ -863,7 +863,7 @@ config_reset(const config_format_t *fmt, void *options,
/** Release storage held by <b>options</b>. */
void
config_free(const config_format_t *fmt, void *options)
config_free_(const config_format_t *fmt, void *options)
{
int i;

View File

@ -177,7 +177,12 @@ typedef struct config_format_t {
#define CAL_WARN_DEPRECATIONS (1u<<2)
void *config_new(const config_format_t *fmt);
void config_free(const config_format_t *fmt, void *options);
void config_free_(const config_format_t *fmt, void *options);
#define config_free(fmt, options) do { \
config_free_((fmt), (options)); \
(options) = NULL; \
} while (0)
config_line_t *config_get_assigned_option(const config_format_t *fmt,
const void *options, const char *key,
int escape_val);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2001 Matej Pfajfar.
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
@ -499,7 +499,7 @@ conn_listener_type_supports_af_unix(int type)
* if <b>conn</b> is an OR or OP connection.
*/
STATIC void
connection_free_(connection_t *conn)
connection_free_minimal(connection_t *conn)
{
void *mem;
size_t memlen;
@ -675,7 +675,7 @@ connection_free_(connection_t *conn)
/** Make sure <b>conn</b> isn't in any of the global conn lists; then free it.
*/
MOCK_IMPL(void,
connection_free,(connection_t *conn))
connection_free_,(connection_t *conn))
{
if (!conn)
return;
@ -704,7 +704,7 @@ connection_free,(connection_t *conn))
}
#endif /* 1 */
connection_unregister_events(conn);
connection_free_(conn);
connection_free_minimal(conn);
}
/**
@ -5239,8 +5239,8 @@ proxy_type_to_string(int proxy_type)
return NULL; /*Unreached*/
}
/** Call connection_free_() on every connection in our array, and release all
* storage held by connection.c.
/** Call connection_free_minimal() on every connection in our array, and
* release all storage held by connection.c.
*
* Don't do the checks in connection_free(), because they will
* fail.
@ -5264,7 +5264,8 @@ connection_free_all(void)
/* Clear out our list of broken connections */
clear_broken_connection_map(0);
SMARTLIST_FOREACH(conns, connection_t *, conn, connection_free_(conn));
SMARTLIST_FOREACH(conns, connection_t *, conn,
connection_free_minimal(conn));
if (outgoing_addrs) {
SMARTLIST_FOREACH(outgoing_addrs, tor_addr_t *, addr, tor_free(addr));

View File

@ -29,7 +29,9 @@ connection_t *connection_new(int type, int socket_family);
int connection_init_accepted_conn(connection_t *conn,
const listener_connection_t *listener);
void connection_link_connections(connection_t *conn_a, connection_t *conn_b);
MOCK_DECL(void,connection_free,(connection_t *conn));
MOCK_DECL(void,connection_free_,(connection_t *conn));
#define connection_free(conn) \
FREE_AND_NULL(connection_t, connection_free_, (conn))
void connection_free_all(void);
void connection_about_to_close_connection(connection_t *conn);
void connection_close_immediate(connection_t *conn);
@ -267,7 +269,7 @@ connection_is_moribund(connection_t *conn)
void connection_check_oos(int n_socks, int failed);
#ifdef CONNECTION_PRIVATE
STATIC void connection_free_(connection_t *conn);
STATIC void connection_free_minimal(connection_t *conn);
/* Used only by connection.c and test*.c */
uint32_t bucket_millis_empty(int tokens_before, uint32_t last_empty_time,

View File

@ -3331,7 +3331,7 @@ handle_hs_exit_conn(circuit_t *circ, edge_connection_t *conn)
relay_send_end_cell_from_edge(conn->stream_id, circ,
END_STREAM_REASON_DONE,
origin_circ->cpath->prev);
connection_free(TO_CONN(conn));
connection_free_(TO_CONN(conn));
/* Drop the circuit here since it might be someone deliberately
* scanning the hidden service ports. Note that this mitigates port
@ -3523,7 +3523,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
if (we_are_hibernating()) {
relay_send_end_cell_from_edge(rh.stream_id, circ,
END_STREAM_REASON_HIBERNATING, NULL);
connection_free(TO_CONN(n_stream));
connection_free_(TO_CONN(n_stream));
return 0;
}
@ -3601,7 +3601,7 @@ connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
return 0;
case 1: /* The result was cached; a resolved cell was sent. */
if (!dummy_conn->base_.marked_for_close)
connection_free(TO_CONN(dummy_conn));
connection_free_(TO_CONN(dummy_conn));
return 0;
case 0: /* resolve added to pending list */
assert_circuit_ok(TO_CIRCUIT(circ));
@ -3774,8 +3774,8 @@ connection_exit_connect_dir(edge_connection_t *exitconn)
if (connection_add(TO_CONN(exitconn))<0) {
connection_edge_end(exitconn, END_STREAM_REASON_RESOURCELIMIT);
connection_free(TO_CONN(exitconn));
connection_free(TO_CONN(dirconn));
connection_free_(TO_CONN(exitconn));
connection_free_(TO_CONN(dirconn));
return 0;
}
@ -3787,7 +3787,7 @@ connection_exit_connect_dir(edge_connection_t *exitconn)
connection_edge_end(exitconn, END_STREAM_REASON_RESOURCELIMIT);
connection_close_immediate(TO_CONN(exitconn));
connection_mark_for_close(TO_CONN(exitconn));
connection_free(TO_CONN(dirconn));
connection_free_(TO_CONN(dirconn));
return 0;
}

View File

@ -505,7 +505,7 @@ var_cell_copy(const var_cell_t *src)
/** Release all space held by <b>cell</b>. */
void
var_cell_free(var_cell_t *cell)
var_cell_free_(var_cell_t *cell)
{
tor_free(cell);
}
@ -1263,7 +1263,7 @@ connection_or_connect, (const tor_addr_t *_addr, uint16_t port,
fmt_addrport(&TO_CONN(conn)->addr, TO_CONN(conn)->port));
}
connection_free(TO_CONN(conn));
connection_free_(TO_CONN(conn));
return NULL;
}
@ -1276,7 +1276,7 @@ connection_or_connect, (const tor_addr_t *_addr, uint16_t port,
connection_or_connect_failed(conn,
errno_to_orconn_end_reason(socket_error),
tor_socket_strerror(socket_error));
connection_free(TO_CONN(conn));
connection_free_(TO_CONN(conn));
return NULL;
case 0:
connection_watch_events(TO_CONN(conn), READ_EVENT | WRITE_EVENT);
@ -1870,7 +1870,7 @@ connection_init_or_handshake_state(or_connection_t *conn, int started_here)
/** Free all storage held by <b>state</b>. */
void
or_handshake_state_free(or_handshake_state_t *state)
or_handshake_state_free_(or_handshake_state_t *state)
{
if (!state)
return;

View File

@ -68,7 +68,9 @@ int connection_or_client_learned_peer_id(or_connection_t *conn,
const ed25519_public_key_t *ed_peer_id);
time_t connection_or_client_used(or_connection_t *conn);
MOCK_DECL(int, connection_or_get_num_circuits, (or_connection_t *conn));
void or_handshake_state_free(or_handshake_state_t *state);
void or_handshake_state_free_(or_handshake_state_t *state);
#define or_handshake_state_free(state) \
FREE_AND_NULL(or_handshake_state_t, or_handshake_state_free_, (state))
void or_handshake_state_record_cell(or_connection_t *conn,
or_handshake_state_t *state,
const cell_t *cell,
@ -105,7 +107,8 @@ int var_cell_pack_header(const var_cell_t *cell, char *hdr_out,
int wide_circ_ids);
var_cell_t *var_cell_new(uint16_t payload_len);
var_cell_t *var_cell_copy(const var_cell_t *src);
void var_cell_free(var_cell_t *cell);
void var_cell_free_(var_cell_t *cell);
#define var_cell_free(cell) FREE_AND_NULL(var_cell_t, var_cell_free_, (cell))
/* DOCDOC */
#define MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS 4

View File

@ -170,7 +170,7 @@ consensus_cache_clear(consensus_cache_t *cache)
* Drop all storage held by <b>cache</b>.
*/
void
consensus_cache_free(consensus_cache_t *cache)
consensus_cache_free_(consensus_cache_t *cache)
{
if (! cache)
return;

View File

@ -10,9 +10,14 @@ typedef struct consensus_cache_entry_t consensus_cache_entry_t;
typedef struct consensus_cache_t consensus_cache_t;
HANDLE_DECL(consensus_cache_entry, consensus_cache_entry_t, )
#define consensus_cache_entry_handle_free(h) \
FREE_AND_NULL(consensus_cache_entry_handle_t, \
consensus_cache_entry_handle_free_, (h))
consensus_cache_t *consensus_cache_open(const char *subdir, int max_entries);
void consensus_cache_free(consensus_cache_t *cache);
void consensus_cache_free_(consensus_cache_t *cache);
#define consensus_cache_free(cache) \
FREE_AND_NULL(consensus_cache_t, consensus_cache_free_, (cache))
struct sandbox_cfg_elem;
int consensus_cache_may_overallocate(consensus_cache_t *cache);
int consensus_cache_register_with_sandbox(consensus_cache_t *cache,

View File

@ -207,9 +207,12 @@ HT_PROTOTYPE(cdm_diff_ht, cdm_diff_t, node, cdm_diff_hash, cdm_diff_eq)
HT_GENERATE2(cdm_diff_ht, cdm_diff_t, node, cdm_diff_hash, cdm_diff_eq,
0.6, tor_reallocarray, tor_free_)
#define cdm_diff_free(diff) \
FREE_AND_NULL(cdm_diff_t, cdm_diff_free_, (diff))
/** Release all storage held in <b>diff</b>. */
static void
cdm_diff_free(cdm_diff_t *diff)
cdm_diff_free_(cdm_diff_t *diff)
{
if (!diff)
return;
@ -1506,11 +1509,15 @@ consensus_diff_worker_threadfn(void *state_, void *work_)
return WQ_RPL_REPLY;
}
#define consensus_diff_worker_job_free(job) \
FREE_AND_NULL(consensus_diff_worker_job_t, \
consensus_diff_worker_job_free_, (job))
/**
* Helper: release all storage held in <b>job</b>.
*/
static void
consensus_diff_worker_job_free(consensus_diff_worker_job_t *job)
consensus_diff_worker_job_free_(consensus_diff_worker_job_t *job)
{
if (!job)
return;
@ -1658,11 +1665,15 @@ typedef struct consensus_compress_worker_job_t {
compressed_result_t out[ARRAY_LENGTH(compress_consensus_with)];
} consensus_compress_worker_job_t;
#define consensus_compress_worker_job_free(job) \
FREE_AND_NULL(consensus_compress_worker_job_t, \
consensus_compress_worker_job_free_, (job))
/**
* Free all resources held in <b>job</b>
*/
static void
consensus_compress_worker_job_free(consensus_compress_worker_job_t *job)
consensus_compress_worker_job_free_(consensus_compress_worker_job_t *job)
{
if (!job)
return;

View File

@ -785,9 +785,12 @@ queue_control_event_string,(uint16_t event, char *msg))
}
}
#define queued_event_free(ev) \
FREE_AND_NULL(queued_event_t, queued_event_free_, (ev))
/** Release all storage held by <b>ev</b>. */
static void
queued_event_free(queued_event_t *ev)
queued_event_free_(queued_event_t *ev)
{
if (ev == NULL)
return;

View File

@ -48,14 +48,25 @@ worker_state_new(void *arg)
ws->onion_keys = server_onion_keys_new();
return ws;
}
#define worker_state_free(ws) \
FREE_AND_NULL(worker_state_t, worker_state_free_, (ws))
static void
worker_state_free(void *arg)
worker_state_free_(worker_state_t *ws)
{
worker_state_t *ws = arg;
if (!ws)
return;
server_onion_keys_free(ws->onion_keys);
tor_free(ws);
}
static void
worker_state_free_void(void *arg)
{
worker_state_free_(arg);
}
static replyqueue_t *replyqueue = NULL;
static threadpool_t *threadpool = NULL;
static struct event *reply_event = NULL;
@ -102,7 +113,7 @@ cpu_init(void)
threadpool = threadpool_new(n_threads,
replyqueue,
worker_state_new,
worker_state_free,
worker_state_free_void,
NULL);
}
/* Total voodoo. Can we make this more sensible? */
@ -198,7 +209,7 @@ cpuworkers_rotate_keyinfo(void)
if (threadpool_queue_update(threadpool,
worker_state_new,
update_state_threadfn,
worker_state_free,
worker_state_free_void,
NULL)) {
log_warn(LD_OR, "Failed to queue key update for worker threads.");
}

View File

@ -41,9 +41,12 @@ typedef struct ddmap_entry_s {
vote_routerstatus_t *vrs_lst[FLEXIBLE_ARRAY_MEMBER];
} ddmap_entry_t;
#define ddmap_entry_free(e) \
FREE_AND_NULL(ddmap_entry_t, ddmap_entry_free_, (e))
/** Release all storage held by e. */
static void
ddmap_entry_free(ddmap_entry_t *e)
ddmap_entry_free_(ddmap_entry_t *e)
{
tor_free(e);
}
@ -158,7 +161,7 @@ dircollator_new(int n_votes, int n_authorities)
/** Release all storage held by <b>dc</b>. */
void
dircollator_free(dircollator_t *dc)
dircollator_free_(dircollator_t *dc)
{
if (!dc)
return;

View File

@ -18,7 +18,9 @@
typedef struct dircollator_s dircollator_t;
dircollator_t *dircollator_new(int n_votes, int n_authorities);
void dircollator_free(dircollator_t *obj);
void dircollator_free_(dircollator_t *obj);
#define dircollator_free(c) \
FREE_AND_NULL(dircollator_t, dircollator_free_, (c))
void dircollator_add_vote(dircollator_t *dc, networkstatus_t *v);
void dircollator_collate(dircollator_t *dc, int consensus_method);

View File

@ -1102,7 +1102,7 @@ directory_request_new(uint8_t dir_purpose)
* Release all resources held by <b>req</b>.
*/
void
directory_request_free(directory_request_t *req)
directory_request_free_(directory_request_t *req)
{
if (req == NULL)
return;

View File

@ -51,7 +51,9 @@ int directory_must_use_begindir(const or_options_t *options);
*/
typedef struct directory_request_t directory_request_t;
directory_request_t *directory_request_new(uint8_t dir_purpose);
void directory_request_free(directory_request_t *req);
void directory_request_free_(directory_request_t *req);
#define directory_request_free(req) \
FREE_AND_NULL(directory_request_t, directory_request_free_, (req))
void directory_request_set_or_addr_port(directory_request_t *req,
const tor_addr_port_t *p);
void directory_request_set_dir_addr_port(directory_request_t *req,

View File

@ -3515,7 +3515,7 @@ spooled_resource_new_from_cache_entry(consensus_cache_entry_t *entry)
/** Release all storage held by <b>spooled</b>. */
void
spooled_resource_free(spooled_resource_t *spooled)
spooled_resource_free_(spooled_resource_t *spooled)
{
if (spooled == NULL)
return;

View File

@ -196,7 +196,9 @@ spooled_resource_t *spooled_resource_new(dir_spool_source_t source,
size_t digestlen);
spooled_resource_t *spooled_resource_new_from_cache_entry(
struct consensus_cache_entry_t *entry);
void spooled_resource_free(spooled_resource_t *spooled);
void spooled_resource_free_(spooled_resource_t *spooled);
#define spooled_resource_free(sp) \
FREE_AND_NULL(spooled_resource_t, spooled_resource_free_, (sp))
void dirserv_spool_remove_missing_and_guess_size(dir_connection_t *conn,
time_t cutoff,
int compression,

View File

@ -2691,7 +2691,7 @@ get_detached_signatures_from_pending_consensuses(pending_consensus_t *pending,
/** Release all storage held in <b>s</b>. */
void
ns_detached_signatures_free(ns_detached_signatures_t *s)
ns_detached_signatures_free_(ns_detached_signatures_t *s)
{
if (!s)
return;
@ -2849,10 +2849,13 @@ get_voting_schedule(const or_options_t *options, time_t now, int severity)
return new_voting_schedule;
}
#define voting_schedule_free(s) \
FREE_AND_NULL(voting_schedule_t, voting_schedule_free_, (s))
/** Frees a voting_schedule_t. This should be used instead of the generic
* tor_free. */
static void
voting_schedule_free(voting_schedule_t *voting_schedule_to_free)
voting_schedule_free_(voting_schedule_t *voting_schedule_to_free)
{
if (!voting_schedule_to_free)
return;

View File

@ -148,7 +148,9 @@ int networkstatus_add_detached_signatures(networkstatus_t *target,
int severity,
const char **msg_out);
char *networkstatus_get_detached_signatures(smartlist_t *consensuses);
void ns_detached_signatures_free(ns_detached_signatures_t *s);
void ns_detached_signatures_free_(ns_detached_signatures_t *s);
#define ns_detached_signatures_free(s) \
FREE_AND_NULL(ns_detached_signatures_t, ns_detached_signatures_free_, (s))
/* cert manipulation */
authority_cert_t *authority_cert_dup(authority_cert_t *cert);

View File

@ -457,7 +457,7 @@ purge_expired_resolves(time_t now)
if (!pendconn->base_.marked_for_close) {
connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT);
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
connection_free(TO_CONN(pendconn));
connection_free_(TO_CONN(pendconn));
}
tor_free(pend);
}
@ -670,7 +670,7 @@ dns_resolve(edge_connection_t *exitconn)
/* If we made the connection pending, then we freed it already in
* dns_cancel_pending_resolve(). If we marked it for close, it'll
* get freed from the main loop. Otherwise, can free it now. */
connection_free(TO_CONN(exitconn));
connection_free_(TO_CONN(exitconn));
}
break;
default:
@ -1101,7 +1101,7 @@ dns_cancel_pending_resolve,(const char *address))
if (circ)
circuit_detach_stream(circ, pendconn);
if (!pendconn->base_.marked_for_close)
connection_free(TO_CONN(pendconn));
connection_free_(TO_CONN(pendconn));
resolve->pending_connections = pend->next;
tor_free(pend);
}
@ -1230,7 +1230,7 @@ inform_pending_connections(cached_resolve_t *resolve)
/* This detach must happen after we send the resolved cell. */
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
}
connection_free(TO_CONN(pendconn));
connection_free_(TO_CONN(pendconn));
} else {
circuit_t *circ;
if (pendconn->base_.purpose == EXIT_PURPOSE_CONNECT) {
@ -1259,7 +1259,7 @@ inform_pending_connections(cached_resolve_t *resolve)
circ = circuit_get_by_edge_conn(pendconn);
tor_assert(circ);
circuit_detach_stream(circ, pendconn);
connection_free(TO_CONN(pendconn));
connection_free_(TO_CONN(pendconn));
}
}
resolve->pending_connections = pend->next;

View File

@ -172,7 +172,7 @@ evdns_server_callback(struct evdns_server_request *req, void *data_)
if (connection_add(ENTRY_TO_CONN(entry_conn)) < 0) {
log_warn(LD_APP, "Couldn't register dummy connection for DNS request");
evdns_server_request_respond(req, DNS_ERR_SERVERFAILED);
connection_free(ENTRY_TO_CONN(entry_conn));
connection_free_(ENTRY_TO_CONN(entry_conn));
return;
}
@ -249,7 +249,7 @@ dnsserv_launch_request(const char *name, int reverse,
if (connection_add(TO_CONN(conn))<0) {
log_warn(LD_APP, "Couldn't register dummy connection for RESOLVE request");
connection_free(TO_CONN(conn));
connection_free_(TO_CONN(conn));
return -1;
}

View File

@ -2196,7 +2196,7 @@ entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b)
/** Release all storage held in <b>restriction</b> */
STATIC void
entry_guard_restriction_free(entry_guard_restriction_t *rst)
entry_guard_restriction_free_(entry_guard_restriction_t *rst)
{
tor_free(rst);
}
@ -2205,7 +2205,7 @@ entry_guard_restriction_free(entry_guard_restriction_t *rst)
* Release all storage held in <b>state</b>.
*/
void
circuit_guard_state_free(circuit_guard_state_t *state)
circuit_guard_state_free_(circuit_guard_state_t *state)
{
if (!state)
return;
@ -3108,7 +3108,7 @@ get_guard_state_for_bridge_desc_fetch(const char *digest)
/** Release all storage held by <b>e</b>. */
STATIC void
entry_guard_free(entry_guard_t *e)
entry_guard_free_(entry_guard_t *e)
{
if (!e)
return;
@ -3601,7 +3601,7 @@ entry_guards_get_err_str_if_dir_info_missing(int using_mds,
/** Free one guard selection context */
STATIC void
guard_selection_free(guard_selection_t *gs)
guard_selection_free_(guard_selection_t *gs)
{
if (!gs) return;

View File

@ -356,7 +356,10 @@ typedef enum {
GUARD_USAGE_DIRGUARD = 1
} guard_usage_t;
void circuit_guard_state_free(circuit_guard_state_t *state);
#define circuit_guard_state_free(val) \
FREE_AND_NULL(circuit_guard_state_t, circuit_guard_state_free_, (val))
void circuit_guard_state_free_(circuit_guard_state_t *state);
int entry_guard_pick_for_circuit(guard_selection_t *gs,
guard_usage_t usage,
entry_guard_restriction_t *rst,
@ -476,6 +479,9 @@ STATIC double get_meaningful_restriction_threshold(void);
STATIC double get_extreme_restriction_threshold(void);
HANDLE_DECL(entry_guard, entry_guard_t, STATIC)
#define entry_guard_handle_free(h) \
FREE_AND_NULL(entry_guard_handle_t, entry_guard_handle_free_, (h))
STATIC guard_selection_type_t guard_selection_infer_type(
guard_selection_type_t type_in,
const char *name);
@ -483,7 +489,9 @@ STATIC guard_selection_t *guard_selection_new(const char *name,
guard_selection_type_t type);
STATIC guard_selection_t *get_guard_selection_by_name(
const char *name, guard_selection_type_t type, int create_if_absent);
STATIC void guard_selection_free(guard_selection_t *gs);
STATIC void guard_selection_free_(guard_selection_t *gs);
#define guard_selection_free(gs) \
FREE_AND_NULL(guard_selection_t, guard_selection_free_, (gs))
MOCK_DECL(STATIC int, entry_guard_is_listed,
(guard_selection_t *gs, const entry_guard_t *guard));
STATIC const char *choose_guard_selection(const or_options_t *options,
@ -504,7 +512,9 @@ STATIC entry_guard_t *entry_guard_add_to_sample(guard_selection_t *gs,
STATIC entry_guard_t *entry_guards_expand_sample(guard_selection_t *gs);
STATIC char *entry_guard_encode_for_state(entry_guard_t *guard);
STATIC entry_guard_t *entry_guard_parse_from_state(const char *s);
STATIC void entry_guard_free(entry_guard_t *e);
#define entry_guard_free(e) \
FREE_AND_NULL(entry_guard_t, entry_guard_free_, (e))
STATIC void entry_guard_free_(entry_guard_t *e);
STATIC void entry_guards_update_filtered_sets(guard_selection_t *gs);
STATIC int entry_guards_all_primary_guards_are_down(guard_selection_t *gs);
/**
@ -567,7 +577,10 @@ STATIC entry_guard_restriction_t *guard_create_exit_restriction(
STATIC entry_guard_restriction_t *guard_create_dirserver_md_restriction(void);
STATIC void entry_guard_restriction_free(entry_guard_restriction_t *rst);
STATIC void entry_guard_restriction_free_(entry_guard_restriction_t *rst);
#define entry_guard_restriction_free(rst) \
FREE_AND_NULL(entry_guard_restriction_t, \
entry_guard_restriction_free_, (rst))
#endif /* defined(ENTRYNODES_PRIVATE) */

View File

@ -40,7 +40,7 @@ ext_or_cmd_new(uint16_t len)
/** Deallocate the Extended ORPort message in <b>cmd</b>. */
void
ext_or_cmd_free(ext_or_cmd_t *cmd)
ext_or_cmd_free_(ext_or_cmd_t *cmd)
{
tor_free(cmd);
}

View File

@ -10,7 +10,11 @@
int connection_ext_or_start_auth(or_connection_t *or_conn);
ext_or_cmd_t *ext_or_cmd_new(uint16_t len);
void ext_or_cmd_free(ext_or_cmd_t *cmd);
#define ext_or_cmd_free(cmd) \
FREE_AND_NULL(ext_or_cmd_t, ext_or_cmd_free_, (cmd))
void ext_or_cmd_free_(ext_or_cmd_t *cmd);
void connection_or_set_ext_or_identifier(or_connection_t *conn);
void connection_or_remove_from_ext_or_id_map(or_connection_t *conn);
void connection_or_clear_ext_or_id_map(void);

View File

@ -196,7 +196,7 @@ fp_pair_map_remove(fp_pair_map_t *map, const fp_pair_t *key)
*/
void
fp_pair_map_free(fp_pair_map_t *map, void (*free_val)(void*))
fp_pair_map_free_(fp_pair_map_t *map, void (*free_val)(void*))
{
fp_pair_map_entry_t **ent, **next, *this;

View File

@ -26,7 +26,12 @@ void * fp_pair_map_get(const fp_pair_map_t *map, const fp_pair_t *key);
void * fp_pair_map_get_by_digests(const fp_pair_map_t *map,
const char *first, const char *second);
void * fp_pair_map_remove(fp_pair_map_t *map, const fp_pair_t *key);
void fp_pair_map_free(fp_pair_map_t *map, void (*free_val)(void*));
void fp_pair_map_free_(fp_pair_map_t *map, void (*free_val)(void*));
#define fp_pair_map_free(map, free_val) do { \
fp_pair_map_free_((map), (free_val)); \
(map) = NULL; \
} while (0)
int fp_pair_map_isempty(const fp_pair_map_t *map);
int fp_pair_map_size(const fp_pair_map_t *map);
fp_pair_map_iter_t * fp_pair_map_iter_init(fp_pair_map_t *map);

View File

@ -527,9 +527,12 @@ HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
HT_GENERATE2(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
#define clientmap_entry_free(ent) \
FREE_AND_NULL(clientmap_entry_t, clientmap_entry_free_, ent)
/** Free all storage held by <b>ent</b>. */
static void
clientmap_entry_free(clientmap_entry_t *ent)
clientmap_entry_free_(clientmap_entry_t *ent)
{
if (!ent)
return;

View File

@ -52,9 +52,12 @@ lookup_v3_desc_as_dir(const uint8_t *key)
return digest256map_get(hs_cache_v3_dir, key);
}
#define cache_dir_desc_free(val) \
FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val))
/* Free a directory descriptor object. */
static void
cache_dir_desc_free(hs_cache_dir_descriptor_t *desc)
cache_dir_desc_free_(hs_cache_dir_descriptor_t *desc)
{
if (desc == NULL) {
return;
@ -67,10 +70,9 @@ cache_dir_desc_free(hs_cache_dir_descriptor_t *desc)
/* Helper function: Use by the free all function using the digest256map
* interface to cache entries. */
static void
cache_dir_desc_free_(void *ptr)
cache_dir_desc_free_void(void *ptr)
{
hs_cache_dir_descriptor_t *desc = ptr;
cache_dir_desc_free(desc);
cache_dir_desc_free_(ptr);
}
/* Create a new directory cache descriptor object from a encoded descriptor.
@ -417,9 +419,12 @@ cache_client_desc_new(const char *desc_str,
return client_desc;
}
#define cache_client_desc_free(val) \
FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
/** Free memory allocated by <b>desc</b>. */
static void
cache_client_desc_free(hs_cache_client_descriptor_t *desc)
cache_client_desc_free_(hs_cache_client_descriptor_t *desc)
{
if (desc == NULL) {
return;
@ -433,7 +438,7 @@ cache_client_desc_free(hs_cache_client_descriptor_t *desc)
/** Helper function: Use by the free all function to clear the client cache */
static void
cache_client_desc_free_(void *ptr)
cache_client_desc_free_void(void *ptr)
{
hs_cache_client_descriptor_t *desc = ptr;
cache_client_desc_free(desc);
@ -448,18 +453,21 @@ cache_intro_state_new(void)
return state;
}
#define cache_intro_state_free(val) \
FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
/* Free an hs_cache_intro_state_t object. */
static void
cache_intro_state_free(hs_cache_intro_state_t *state)
cache_intro_state_free_(hs_cache_intro_state_t *state)
{
tor_free(state);
}
/* Helper function: use by the free all function. */
static void
cache_intro_state_free_(void *state)
cache_intro_state_free_void(void *state)
{
cache_intro_state_free(state);
cache_intro_state_free_(state);
}
/* Return a newly allocated and initialized hs_cache_client_intro_state_t
@ -472,22 +480,26 @@ cache_client_intro_state_new(void)
return cache;
}
#define cache_client_intro_state_free(val) \
FREE_AND_NULL(hs_cache_client_intro_state_t, \
cache_client_intro_state_free_, (val))
/* Free a cache client intro state object. */
static void
cache_client_intro_state_free(hs_cache_client_intro_state_t *cache)
cache_client_intro_state_free_(hs_cache_client_intro_state_t *cache)
{
if (cache == NULL) {
return;
}
digest256map_free(cache->intro_points, cache_intro_state_free_);
digest256map_free(cache->intro_points, cache_intro_state_free_void);
tor_free(cache);
}
/* Helper function: use by the free all function. */
static void
cache_client_intro_state_free_(void *entry)
cache_client_intro_state_free_void(void *entry)
{
cache_client_intro_state_free(entry);
cache_client_intro_state_free_(entry);
}
/* For the given service identity key service_pk and an introduction
@ -951,14 +963,14 @@ hs_cache_init(void)
void
hs_cache_free_all(void)
{
digest256map_free(hs_cache_v3_dir, cache_dir_desc_free_);
digest256map_free(hs_cache_v3_dir, cache_dir_desc_free_void);
hs_cache_v3_dir = NULL;
digest256map_free(hs_cache_v3_client, cache_client_desc_free_);
digest256map_free(hs_cache_v3_client, cache_client_desc_free_void);
hs_cache_v3_client = NULL;
digest256map_free(hs_cache_client_intro_state,
cache_client_intro_state_free_);
cache_client_intro_state_free_void);
hs_cache_client_intro_state = NULL;
}

View File

@ -106,9 +106,12 @@ hs_token_new(hs_token_type_t type, size_t token_len,
return hs_token;
}
#define hs_token_free(val) \
FREE_AND_NULL(hs_token_t, hs_token_free_, (val))
/** Free memory allocated by this <b>hs_token</b>. */
static void
hs_token_free(hs_token_t *hs_token)
hs_token_free_(hs_token_t *hs_token)
{
if (!hs_token) {
return;

View File

@ -329,7 +329,7 @@ rend_data_alloc(uint32_t version)
/** Free all storage associated with <b>data</b> */
void
rend_data_free(rend_data_t *data)
rend_data_free_(rend_data_t *data)
{
if (!data) {
return;

View File

@ -192,7 +192,9 @@ void hs_build_blinded_keypair(const ed25519_keypair_t *kp,
ed25519_keypair_t *kp_out);
int hs_service_requires_uptime_circ(const smartlist_t *ports);
void rend_data_free(rend_data_t *data);
void rend_data_free_(rend_data_t *data);
#define rend_data_free(data) \
FREE_AND_NULL(rend_data_t, rend_data_free_, (data))
rend_data_t *rend_data_dup(const rend_data_t *data);
rend_data_t *rend_data_client_create(const char *onion_address,
const char *desc_id,

View File

@ -2367,7 +2367,7 @@ hs_desc_encode_descriptor,(const hs_descriptor_t *desc,
/* Free the descriptor plaintext data object. */
void
hs_desc_plaintext_data_free(hs_desc_plaintext_data_t *desc)
hs_desc_plaintext_data_free_(hs_desc_plaintext_data_t *desc)
{
desc_plaintext_data_free_contents(desc);
tor_free(desc);
@ -2375,7 +2375,7 @@ hs_desc_plaintext_data_free(hs_desc_plaintext_data_t *desc)
/* Free the descriptor encrypted data object. */
void
hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc)
hs_desc_encrypted_data_free_(hs_desc_encrypted_data_t *desc)
{
desc_encrypted_data_free_contents(desc);
tor_free(desc);
@ -2383,7 +2383,7 @@ hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc)
/* Free the given descriptor object. */
void
hs_descriptor_free(hs_descriptor_t *desc)
hs_descriptor_free_(hs_descriptor_t *desc)
{
if (!desc) {
return;
@ -2448,7 +2448,7 @@ hs_desc_intro_point_new(void)
/* Free a descriptor intro point object. */
void
hs_desc_intro_point_free(hs_desc_intro_point_t *ip)
hs_desc_intro_point_free_(hs_desc_intro_point_t *ip)
{
if (ip == NULL) {
return;
@ -2467,7 +2467,7 @@ hs_desc_intro_point_free(hs_desc_intro_point_t *ip)
/* Free the given descriptor link specifier. */
void
hs_desc_link_specifier_free(hs_desc_link_specifier_t *ls)
hs_desc_link_specifier_free_(hs_desc_link_specifier_t *ls)
{
if (ls == NULL) {
return;

View File

@ -208,11 +208,20 @@ hs_desc_is_supported_version(uint32_t version)
/* Public API. */
void hs_descriptor_free(hs_descriptor_t *desc);
void hs_desc_plaintext_data_free(hs_desc_plaintext_data_t *desc);
void hs_desc_encrypted_data_free(hs_desc_encrypted_data_t *desc);
void hs_descriptor_free_(hs_descriptor_t *desc);
#define hs_descriptor_free(desc) \
FREE_AND_NULL(hs_descriptor_t, hs_descriptor_free_, (desc))
void hs_desc_plaintext_data_free_(hs_desc_plaintext_data_t *desc);
#define hs_desc_plaintext_data_free(desc) \
FREE_AND_NULL(hs_desc_plaintext_data_t, hs_desc_plaintext_data_free_, (desc))
void hs_desc_encrypted_data_free_(hs_desc_encrypted_data_t *desc);
#define hs_desc_encrypted_data_free(desc) \
FREE_AND_NULL(hs_desc_encrypted_data_t, hs_desc_encrypted_data_free_, (desc))
void hs_desc_link_specifier_free_(hs_desc_link_specifier_t *ls);
#define hs_desc_link_specifier_free(ls) \
FREE_AND_NULL(hs_desc_link_specifier_t, hs_desc_link_specifier_free_, (ls))
void hs_desc_link_specifier_free(hs_desc_link_specifier_t *ls);
hs_desc_link_specifier_t *hs_desc_link_specifier_new(
const extend_info_t *info, uint8_t type);
void hs_descriptor_clear_intro_points(hs_descriptor_t *desc);
@ -234,7 +243,9 @@ size_t hs_desc_obj_size(const hs_descriptor_t *data);
size_t hs_desc_plaintext_obj_size(const hs_desc_plaintext_data_t *data);
hs_desc_intro_point_t *hs_desc_intro_point_new(void);
void hs_desc_intro_point_free(hs_desc_intro_point_t *ip);
void hs_desc_intro_point_free_(hs_desc_intro_point_t *ip);
#define hs_desc_intro_point_free(ip) \
FREE_AND_NULL(hs_desc_intro_point_t, hs_desc_intro_point_free_, (ip))
link_specifier_t *hs_desc_lspec_to_trunnel(
const hs_desc_link_specifier_t *spec);

View File

@ -25,7 +25,7 @@ hs_ident_circuit_new(const ed25519_public_key_t *identity_pk,
/* Free the given circuit identifier. */
void
hs_ident_circuit_free(hs_ident_circuit_t *ident)
hs_ident_circuit_free_(hs_ident_circuit_t *ident)
{
if (ident == NULL) {
return;
@ -56,7 +56,7 @@ hs_ident_dir_conn_dup(const hs_ident_dir_conn_t *src)
/* Free the given directory connection identifier. */
void
hs_ident_dir_conn_free(hs_ident_dir_conn_t *ident)
hs_ident_dir_conn_free_(hs_ident_dir_conn_t *ident)
{
if (ident == NULL) {
return;
@ -93,7 +93,7 @@ hs_ident_edge_conn_new(const ed25519_public_key_t *identity_pk)
/* Free the given edge connection identifier. */
void
hs_ident_edge_conn_free(hs_ident_edge_conn_t *ident)
hs_ident_edge_conn_free_(hs_ident_edge_conn_t *ident)
{
if (ident == NULL) {
return;

View File

@ -119,12 +119,16 @@ typedef struct hs_ident_edge_conn_t {
hs_ident_circuit_t *hs_ident_circuit_new(
const ed25519_public_key_t *identity_pk,
hs_ident_circuit_type_t circuit_type);
void hs_ident_circuit_free(hs_ident_circuit_t *ident);
void hs_ident_circuit_free_(hs_ident_circuit_t *ident);
#define hs_ident_circuit_free(id) \
FREE_AND_NULL(hs_ident_circuit_t, hs_ident_circuit_free_, (id))
hs_ident_circuit_t *hs_ident_circuit_dup(const hs_ident_circuit_t *src);
/* Directory connection identifier API. */
hs_ident_dir_conn_t *hs_ident_dir_conn_dup(const hs_ident_dir_conn_t *src);
void hs_ident_dir_conn_free(hs_ident_dir_conn_t *ident);
void hs_ident_dir_conn_free_(hs_ident_dir_conn_t *ident);
#define hs_ident_dir_conn_free(id) \
FREE_AND_NULL(hs_ident_dir_conn_t, hs_ident_dir_conn_free_, (id))
void hs_ident_dir_conn_init(const ed25519_public_key_t *identity_pk,
const ed25519_public_key_t *blinded_pk,
hs_ident_dir_conn_t *ident);
@ -132,7 +136,9 @@ void hs_ident_dir_conn_init(const ed25519_public_key_t *identity_pk,
/* Edge connection identifier API. */
hs_ident_edge_conn_t *hs_ident_edge_conn_new(
const ed25519_public_key_t *identity_pk);
void hs_ident_edge_conn_free(hs_ident_edge_conn_t *ident);
void hs_ident_edge_conn_free_(hs_ident_edge_conn_t *ident);
#define hs_ident_edge_conn_free(id) \
FREE_AND_NULL(hs_ident_edge_conn_t, hs_ident_edge_conn_free_, (id))
/* Validators */
int hs_ident_intro_circ_is_valid(const hs_ident_circuit_t *ident);

View File

@ -353,7 +353,7 @@ service_free_all(void)
/* Free a given service intro point object. */
STATIC void
service_intro_point_free(hs_service_intro_point_t *ip)
service_intro_point_free_(hs_service_intro_point_t *ip)
{
if (!ip) {
return;
@ -369,9 +369,9 @@ service_intro_point_free(hs_service_intro_point_t *ip)
/* Helper: free an hs_service_intro_point_t object. This function is used by
* digest256map_free() which requires a void * pointer. */
static void
service_intro_point_free_(void *obj)
service_intro_point_free_void(void *obj)
{
service_intro_point_free(obj);
service_intro_point_free_(obj);
}
/* Return a newly allocated service intro point and fully initialized from the
@ -1028,7 +1028,7 @@ load_service_keys(hs_service_t *service)
/* Free a given service descriptor object and all key material is wiped. */
STATIC void
service_descriptor_free(hs_service_descriptor_t *desc)
service_descriptor_free_(hs_service_descriptor_t *desc)
{
if (!desc) {
return;
@ -1037,7 +1037,7 @@ service_descriptor_free(hs_service_descriptor_t *desc)
memwipe(&desc->signing_kp, 0, sizeof(desc->signing_kp));
memwipe(&desc->blinded_kp, 0, sizeof(desc->blinded_kp));
/* Cleanup all intro points. */
digest256map_free(desc->intro_points.map, service_intro_point_free_);
digest256map_free(desc->intro_points.map, service_intro_point_free_void);
digestmap_free(desc->intro_points.failed_id, tor_free_);
if (desc->previous_hsdirs) {
SMARTLIST_FOREACH(desc->previous_hsdirs, char *, s, tor_free(s));
@ -3441,7 +3441,7 @@ hs_service_new(const or_options_t *options)
* also takes care of wiping service keys from memory. It is safe to pass a
* NULL pointer. */
void
hs_service_free(hs_service_t *service)
hs_service_free_(hs_service_t *service)
{
if (service == NULL) {
return;

View File

@ -249,7 +249,8 @@ void hs_service_free_all(void);
/* Service new/free functions. */
hs_service_t *hs_service_new(const or_options_t *options);
void hs_service_free(hs_service_t *service);
void hs_service_free_(hs_service_t *service);
#define hs_service_free(s) FREE_AND_NULL(hs_service_t, hs_service_free_, (s))
unsigned int hs_service_get_num_services(void);
void hs_service_stage_services(const smartlist_t *service_list);
@ -289,12 +290,15 @@ void hs_service_upload_desc_to_dir(const char *encoded_desc,
#ifdef HS_SERVICE_PRIVATE
#ifdef TOR_UNIT_TESTS
/* Useful getters for unit tests. */
STATIC unsigned int get_hs_service_map_size(void);
STATIC int get_hs_service_staging_list_size(void);
STATIC hs_service_ht *get_hs_service_map(void);
STATIC hs_service_t *get_first_service(void);
STATIC hs_service_intro_point_t *service_intro_point_find_by_ident(
const hs_service_t *service,
const hs_ident_circuit_t *ident);
#endif
/* Service accessors. */
STATIC hs_service_t *find_service(hs_service_ht *map,
@ -305,7 +309,10 @@ STATIC int register_service(hs_service_ht *map, hs_service_t *service);
STATIC hs_service_intro_point_t *service_intro_point_new(
const extend_info_t *ei,
unsigned int is_legacy);
STATIC void service_intro_point_free(hs_service_intro_point_t *ip);
STATIC void service_intro_point_free_(hs_service_intro_point_t *ip);
#define service_intro_point_free(ip) \
FREE_AND_NULL(hs_service_intro_point_t, \
service_intro_point_free_, (ip))
STATIC void service_intro_point_add(digest256map_t *map,
hs_service_intro_point_t *ip);
STATIC void service_intro_point_remove(const hs_service_t *service,
@ -313,9 +320,6 @@ STATIC void service_intro_point_remove(const hs_service_t *service,
STATIC hs_service_intro_point_t *service_intro_point_find(
const hs_service_t *service,
const ed25519_public_key_t *auth_key);
STATIC hs_service_intro_point_t *service_intro_point_find_by_ident(
const hs_service_t *service,
const hs_ident_circuit_t *ident);
/* Service descriptor functions. */
STATIC hs_service_descriptor_t *service_descriptor_new(void);
STATIC hs_service_descriptor_t *service_desc_find_by_intro(
@ -341,7 +345,10 @@ STATIC void run_upload_descriptor_event(time_t now);
STATIC char *
encode_desc_rev_counter_for_state(const hs_service_descriptor_t *desc);
STATIC void service_descriptor_free(hs_service_descriptor_t *desc);
STATIC void service_descriptor_free_(hs_service_descriptor_t *desc);
#define service_descriptor_free(d) \
FREE_AND_NULL(hs_service_descriptor_t, \
service_descriptor_free_, (d))
STATIC uint64_t
check_state_line_for_service_rev_counter(const char *state_line,
@ -361,8 +368,6 @@ STATIC void service_desc_schedule_upload(hs_service_descriptor_t *desc,
STATIC int service_desc_hsdirs_changed(const hs_service_t *service,
const hs_service_descriptor_t *desc);
#endif /* defined(TOR_UNIT_TESTS) */
#endif /* defined(HS_SERVICE_PRIVATE) */
#endif /* !defined(TOR_HS_SERVICE_H) */

View File

@ -38,8 +38,10 @@ smartlist_t *microdesc_list_missing_digest256(networkstatus_t *ns,
digest256map_t *skip);
void microdesc_free_(microdesc_t *md, const char *fname, int line);
#define microdesc_free(md) \
microdesc_free_((md), __FILE__, __LINE__)
#define microdesc_free(md) do { \
microdesc_free_((md), __FILE__, __LINE__); \
(md) = NULL; \
} while (0)
void microdesc_free_all(void);
void update_microdesc_downloads(time_t now);

Some files were not shown because too many files have changed in this diff Show More