diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 75717c337b..65ec80aaf9 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1071,6 +1071,13 @@ parse_socks_policy(void)
}
}
+void
+free_socks_policy(void)
+{
+ addr_policy_free(socks_policy);
+ socks_policy = NULL;
+}
+
/** Return 1 if addr is permitted to connect to our socks port,
* based on socks_policy. Else return 0.
*/
@@ -1242,6 +1249,12 @@ void client_dns_clean(void)
strmap_foreach(client_dns_map, (strmap_foreach_fn)_remove_if_expired, &now);
}
+void client_dns_free_all(void)
+{
+ strmap_free(client_dns_map, free);
+ client_dns_map = NULL;
+}
+
/** Make connection redirection follow the provided list of
* exit_redirect_t */
void
diff --git a/src/or/directory.c b/src/or/directory.c
index 6cb6b64c93..e3087a9cc5 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -88,6 +88,13 @@ parse_dir_policy(void)
}
}
+void
+free_dir_policy(void)
+{
+ addr_policy_free(dir_policy);
+ dir_policy = NULL;
+}
+
/** Return 1 if addr is permitted to connect to our dir port,
* based on dir_policy. Else return 0.
*/
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 610cbf5e37..dac5105ab5 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -998,3 +998,31 @@ size_t dirserv_get_runningrouters(const char **rr, int compress)
return compress ? the_runningrouters_z_len : the_runningrouters_len;
}
+void
+dirserv_free_all(void)
+{
+ if (fingerprint_list) {
+ SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, fp,
+ { tor_free(fp->nickname);
+ tor_free(fp->fingerprint);
+ tor_free(fp); });
+ smartlist_free(fingerprint_list);
+ fingerprint_list = NULL;
+ }
+ if (descriptor_list) {
+ SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t*, d,
+ free_descriptor_entry(d));
+ smartlist_free(descriptor_list);
+ descriptor_list = NULL;
+ }
+ tor_free(the_directory);
+ tor_free(the_directory_z);
+ the_directory_len = 0;
+ the_directory_z_len = 0;
+ tor_free(cached_directory.dir);
+ tor_free(cached_directory.dir_z);
+ tor_free(cached_runningrouters.dir);
+ tor_free(cached_runningrouters.dir_z);
+ memset(&cached_directory, 0, sizeof(cached_directory));
+ memset(&cached_runningrouters, 0, sizeof(cached_runningrouters));
+}
diff --git a/src/or/main.c b/src/or/main.c
index 81ef0e0923..4035dc6d2e 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1304,8 +1304,23 @@ static int tor_init(int argc, char *argv[]) {
*
* Also valgrind should then report 0 reachable in its
* leak report */
-void tor_free_all(void) {
-
+void tor_free_all(void)
+{
+ routerlist_free_current();
+ free_trusted_dir_servers();
+ client_dns_free_all();
+ free_socks_policy();
+ free_dir_policy();
+ dirserv_free_all();
+ rend_service_free_all();
+ rep_hist_free_all();
+ /* cache in dns.c */
+ /* onion queue in onion.c */
+ /* the circuits. */
+ /* the connections. */
+ /* the config */
+ /* My routerinfo_t */
+ /* all keys. */
}
/** Do whatever cleanup is necessary before shutting Tor down. */
diff --git a/src/or/or.h b/src/or/or.h
index 39cb83c112..08fb96c1da 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1256,6 +1256,7 @@ void connection_ap_expire_beginning(void);
void connection_ap_attach_pending(void);
void parse_socks_policy(void);
+void free_socks_policy(void);
int socks_policy_permits_address(uint32_t addr);
void client_dns_init(void);
@@ -1263,6 +1264,7 @@ uint32_t client_dns_lookup_entry(const char *address);
int client_dns_incr_failures(const char *address);
void client_dns_set_entry(const char *address, uint32_t val);
void client_dns_clean(void);
+void client_dns_free_all(void);
void set_exit_redirects(smartlist_t *lst);
typedef enum hostname_type_t {
NORMAL_HOSTNAME, ONION_HOSTNAME, EXIT_HOSTNAME
@@ -1346,6 +1348,7 @@ int connection_dir_finished_flushing(connection_t *conn);
int connection_dir_finished_connecting(connection_t *conn);
void connection_dir_connect_failed(connection_t *conn);
void parse_dir_policy(void);
+void free_dir_policy(void);
/********************************* dirserv.c ***************************/
@@ -1365,6 +1368,7 @@ size_t dirserv_get_directory(const char **cp, int compress);
size_t dirserv_get_runningrouters(const char **rr, int compress);
void dirserv_set_cached_directory(const char *directory, time_t when,
int is_running_routers);
+void dirserv_free_all(void);
/********************************* dns.c ***************************/
@@ -1492,6 +1496,8 @@ int rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capac
void rep_hist_note_used_resolve(time_t now);
int rep_hist_get_predicted_resolve(time_t now);
+void rep_hist_free_all(void);
+
/********************************* rendclient.c ***************************/
void rend_client_introcirc_has_opened(circuit_t *circ);
@@ -1558,6 +1564,7 @@ int rend_service_introduce(circuit_t *circuit, const char *request, size_t reque
void rend_service_relaunch_rendezvous(circuit_t *oldcirc);
int rend_service_set_connection_addr_port(connection_t *conn, circuit_t *circ);
void rend_service_dump_stats(int severity);
+void rend_service_free_all(void);
/********************************* rendmid.c *******************************/
int rend_mid_establish_intro(circuit_t *circ, const char *request, size_t request_len);
@@ -1646,6 +1653,8 @@ void router_get_routerlist(routerlist_t **prouterlist);
time_t routerlist_get_published_time(void);
void routerlist_free(routerlist_t *routerlist);
void routerinfo_free(routerinfo_t *router);
+void routerlist_free_current(void);
+void free_trusted_dir_servers(void);
routerinfo_t *routerinfo_copy(const routerinfo_t *router);
void router_mark_as_down(const char *digest);
void routerlist_remove_old_routers(int age);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index d604cdc6ad..1093760968 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -80,7 +80,7 @@ static void rend_service_free(rend_service_t *service)
/** Release all the storage held in rend_service_list, and allocate a new,
* empty rend_service_list.
*/
-static void rend_service_free_all(void)
+void rend_service_free_all(void)
{
if (!rend_service_list) {
rend_service_list = smartlist_create();
@@ -89,7 +89,7 @@ static void rend_service_free_all(void)
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, ptr,
rend_service_free(ptr));
smartlist_free(rend_service_list);
- rend_service_list = smartlist_create();
+ rend_service_list = NULL;
}
/** Validate service and add it to rend_service_list if possible.
@@ -190,8 +190,10 @@ int rend_config_services(or_options_t *options, int validate_only)
rend_service_t *service = NULL;
rend_service_port_config_t *portcfg;
- if (!validate_only)
+ if (!validate_only) {
rend_service_free_all();
+ rend_service_list = smartlist_create();
+ }
for (line = options->RendConfigLines; line; line = line->next) {
if (!strcasecmp(line->key, "HiddenServiceDir")) {
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 4537032803..4076638153 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -730,3 +730,9 @@ int rep_hist_get_predicted_hidserv(time_t now, int *need_uptime, int *need_capac
void rep_hist_note_used_resolve(time_t now) { }
int rep_hist_get_predicted_resolve(time_t now) { return 0; }
+void rep_hist_free_all(void)
+{
+ strmap_free(history_map, free_or_history);
+ tor_free(read_array);
+ tor_free(write_array);
+}
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index fe0b298d6b..db9f08b6d3 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -716,6 +716,22 @@ void routerlist_free(routerlist_t *rl)
tor_free(rl);
}
+void routerlist_free_current(void)
+{
+ routerlist_free(routerlist);
+ routerlist = NULL;
+}
+
+void free_trusted_dir_servers(void)
+{
+ if (trusted_dir_servers) {
+ SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
+ { tor_free(ds->address); tor_free(ds); });
+ smartlist_free(trusted_dir_servers);
+ trusted_dir_servers = NULL;
+ }
+}
+
/** Mark the router with ID digest as non-running in our routerlist. */
void router_mark_as_down(const char *digest) {
routerinfo_t *router;