Browse Source

Free even more things on shutdown. Temporarily move tor_free_all out from #ifdef so it gets tested more.

svn:r3614
Nick Mathewson 19 years ago
parent
commit
f672577bc6
8 changed files with 88 additions and 9 deletions
  1. 18 0
      src/or/circuitlist.c
  2. 7 0
      src/or/config.c
  3. 21 0
      src/or/dns.c
  4. 9 8
      src/or/main.c
  5. 12 0
      src/or/onion.c
  6. 6 0
      src/or/or.h
  7. 2 1
      src/or/rephist.c
  8. 13 0
      src/or/router.c

+ 18 - 0
src/or/circuitlist.c

@@ -149,6 +149,24 @@ static void circuit_free_cpath(crypt_path_t *cpath) {
   circuit_free_cpath_node(cpath);
 }
 
+/** Release all storage held by circuits. */
+void
+circuit_free_all(void)
+{
+  circuit_t *next;
+  while (global_circuitlist) {
+    next = global_circuitlist->next;
+    while (global_circuitlist->resolving_streams) {
+      connection_t *next;
+      next = global_circuitlist->resolving_streams->next_stream;
+      connection_free(global_circuitlist->resolving_streams);
+      global_circuitlist->resolving_streams = next;
+    }
+    circuit_free(global_circuitlist);
+    global_circuitlist = next;
+  }
+}
+
 /** Deallocate space associated with the cpath node <b>victim</b>. */
 static void
 circuit_free_cpath_node(crypt_path_t *victim) {

+ 7 - 0
src/or/config.c

@@ -232,6 +232,13 @@ set_options(or_options_t *new_val) {
   global_options = new_val;
 }
 
+void
+config_free_all(void)
+{
+  options_free(global_options);
+  tor_free(config_fname);
+}
+
 /** Fetch the active option list, and take actions based on it. All
  * of the things we do should survive being done repeatedly.
  * Return 0 if all goes well, return -1 if it's time to die.

+ 21 - 0
src/or/dns.c

@@ -99,6 +99,27 @@ void dns_init(void) {
   spawn_enough_dnsworkers();
 }
 
+static void
+_free_cached_resolve(struct cached_resolve *r) {
+  while(r->pending_connections) {
+    struct pending_connection_t *victim = r->pending_connections;
+    r->pending_connections = victim->next;
+    tor_free(victim);
+  }
+  tor_free(r);
+}
+
+void
+dns_free_all(void)
+{
+  struct cached_resolve *ptr, *next;
+  for (ptr = SPLAY_MIN(cache_tree, &cache_root); ptr != NULL; ptr = next) {
+    next = SPLAY_NEXT(cache_tree, &cache_root, ptr);
+    SPLAY_REMOVE(cache_tree, &cache_root, ptr);
+    _free_cached_resolve(ptr);
+  }
+}
+
 /** Linked list of resolved addresses, oldest to newest. */
 static struct cached_resolve *oldest_cached_resolve = NULL;
 static struct cached_resolve *newest_cached_resolve = NULL;

+ 9 - 8
src/or/main.c

@@ -1314,13 +1314,14 @@ void tor_free_all(void)
   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. */
+  dns_free_all();
+  clear_pending_onions();
+  circuit_free_all();
+  connection_free_all();
+  config_free_all();
+  router_free_all_keys();
+  /* stuff in main.c */
+  smartlist_free(closeable_connection_lst);
 }
 
 /** Do whatever cleanup is necessary before shutting Tor down. */
@@ -1333,8 +1334,8 @@ void tor_cleanup(void) {
   crypto_global_cleanup();
   if (accounting_is_enabled(options))
     accounting_record_bandwidth_usage(time(NULL));
+  tor_free_all(); /* move tor_free_all back into the ifdef below later. XXX*/
 #ifdef USE_DMALLOC
-  tor_free_all();
   dmalloc_log_unfreed();
   dmalloc_shutdown();
 #endif

+ 12 - 0
src/or/onion.c

@@ -316,3 +316,15 @@ onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
   return 0;
 }
 
+/** Remove all circuits from the pending list.  Called from tor_free_all. */
+void
+clear_pending_onions(void)
+{
+  while (ol_list) {
+    struct onion_queue_t *victim = ol_list;
+    ol_list = victim->next;
+    tor_free(victim);
+  }
+  ol_list = ol_tail = NULL;
+  ol_length = 0;
+}

+ 6 - 0
src/or/or.h

@@ -1105,6 +1105,7 @@ int _circuit_mark_for_close(circuit_t *circ);
 
 void assert_cpath_layer_ok(const crypt_path_t *cp);
 void assert_circuit_ok(const circuit_t *c);
+void circuit_free_all(void);
 
 /********************************* circuituse.c ************************/
 
@@ -1144,6 +1145,7 @@ struct config_line_t {
 or_options_t *get_options(void);
 void set_options(or_options_t *new_val);
 int options_act(void);
+void config_free_all(void);
 
 int config_get_lines(char *string, struct config_line_t **result);
 void config_free_lines(struct config_line_t *front);
@@ -1373,6 +1375,7 @@ void dirserv_free_all(void);
 /********************************* dns.c ***************************/
 
 void dns_init(void);
+void dns_free_all(void);
 int connection_dns_finished_flushing(connection_t *conn);
 int connection_dns_reached_eof(connection_t *conn);
 int connection_dns_process_inbuf(connection_t *conn);
@@ -1451,6 +1454,8 @@ int onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
                              char *key_out,
                              size_t key_out_len);
 
+void clear_pending_onions(void);
+
 /********************************* relay.c ***************************/
 
 extern unsigned long stats_n_relay_cells_relayed;
@@ -1601,6 +1606,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
                                  crypto_pk_env_t *ident_key);
 int is_legal_nickname(const char *s);
 int is_legal_nickname_or_hexdigest(const char *s);
+void router_free_all_keys(void);
 
 /********************************* routerlist.c ***************************/
 

+ 2 - 1
src/or/rephist.c

@@ -106,8 +106,9 @@ _free_link_history(void *val)
 }
 
 static void
-free_or_history(or_history_t *hist)
+free_or_history(void *_hist)
 {
+  or_history_t *hist = _hist;
   strmap_free(hist->link_history_map, _free_link_history);
   tor_free(hist);
 }

+ 13 - 0
src/or/router.c

@@ -829,3 +829,16 @@ int is_legal_nickname_or_hexdigest(const char *s)
   return len == HEX_DIGEST_LEN+1 && strspn(s+1,HEX_CHARACTERS)==len-1;
 }
 
+void router_free_all_keys(void)
+{
+  if (onionkey)
+    crypto_free_pk_env(onionkey);
+  if (lastonionkey)
+    crypto_free_pk_env(lastonionkey);
+  if (identitykey)
+    crypto_free_pk_env(identitykey);
+  if (key_lock)
+    tor_mutex_free(key_lock);
+  if (desc_routerinfo)
+    routerinfo_free(desc_routerinfo);
+}