[tor-commits] [tor/master] Merge branch 'macro_free_v2_squashed'

nickm at torproject.org nickm at torproject.org
Fri Dec 8 20:04:29 UTC 2017


commit 5ee0cccd49e57fad8c810e817d912d4a61dbc96c
Merge: 44010c6fc 7ca5f4bf0
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Dec 8 14:58:43 2017 -0500

    Merge branch 'macro_free_v2_squashed'

 changes/bug24337               |  8 ++++
 configure.ac                   |  1 -
 doc/HACKING/CodingStandards.md | 40 ++++++++++++++++++
 src/common/address.c           |  6 +--
 src/common/address.h           | 13 +++---
 src/common/aes.c               |  4 +-
 src/common/aes.h               |  4 +-
 src/common/buffers.c           |  2 +-
 src/common/buffers.h           |  3 +-
 src/common/compat.c            |  5 ++-
 src/common/compat_libevent.c   |  4 +-
 src/common/compat_libevent.h   |  8 +++-
 src/common/compat_threads.c    |  4 +-
 src/common/compat_threads.h    |  6 ++-
 src/common/compress.c          |  2 +-
 src/common/compress.h          |  4 +-
 src/common/compress_lzma.c     |  2 +-
 src/common/compress_lzma.h     |  5 ++-
 src/common/compress_zlib.c     |  2 +-
 src/common/compress_zlib.h     |  5 ++-
 src/common/compress_zstd.c     |  2 +-
 src/common/compress_zstd.h     |  5 ++-
 src/common/confline.c          |  2 +-
 src/common/confline.h          |  7 ++-
 src/common/container.c         | 19 ++++++---
 src/common/container.h         | 27 +++++++++---
 src/common/crypto.c            | 10 ++---
 src/common/crypto.h            | 19 ++++++---
 src/common/crypto_ed25519.c    |  2 +-
 src/common/crypto_ed25519.h    |  5 ++-
 src/common/di_ops.c            |  2 +-
 src/common/di_ops.h            |  7 ++-
 src/common/handles.h           |  4 +-
 src/common/log.c               | 11 +++--
 src/common/memarea.c           |  2 +-
 src/common/memarea.h           |  7 ++-
 src/common/procmon.c           |  2 +-
 src/common/procmon.h           |  4 +-
 src/common/sandbox.c           |  6 ++-
 src/common/storagedir.c        |  2 +-
 src/common/storagedir.h        |  5 ++-
 src/common/timers.c            |  2 +-
 src/common/timers.h            |  3 +-
 src/common/tortls.c            |  4 +-
 src/common/tortls.h            |  7 ++-
 src/common/util.c              |  2 +-
 src/common/util.h              | 25 ++++++++++-
 src/common/workqueue.c         |  5 ++-
 src/or/addressmap.c            | 35 ++++++++++-----
 src/or/bridges.c               |  7 ++-
 src/or/channel.c               | 26 ++++++------
 src/or/channel.h               |  9 +++-
 src/or/circuitbuild.c          |  2 +-
 src/or/circuitbuild.h          |  4 +-
 src/or/circuitlist.c           |  4 +-
 src/or/circuitlist.h           |  3 +-
 src/or/circuitmux.c            |  2 +-
 src/or/circuitmux.h            |  4 +-
 src/or/config.c                | 10 +++--
 src/or/config.h                | 12 ++++--
 src/or/confparse.c             |  2 +-
 src/or/confparse.h             |  7 ++-
 src/or/connection.c            | 15 ++++---
 src/or/connection.h            |  6 ++-
 src/or/connection_edge.c       | 12 +++---
 src/or/connection_or.c         |  8 ++--
 src/or/connection_or.h         |  7 ++-
 src/or/conscache.c             |  2 +-
 src/or/conscache.h             |  7 ++-
 src/or/consdiffmgr.c           | 17 ++++++--
 src/or/control.c               |  5 ++-
 src/or/cpuworker.c             | 19 +++++++--
 src/or/dircollate.c            |  7 ++-
 src/or/dircollate.h            |  4 +-
 src/or/directory.c             |  2 +-
 src/or/directory.h             |  4 +-
 src/or/dirserv.c               |  2 +-
 src/or/dirserv.h               |  4 +-
 src/or/dirvote.c               |  7 ++-
 src/or/dirvote.h               |  4 +-
 src/or/dns.c                   | 10 ++---
 src/or/dnsserv.c               |  4 +-
 src/or/entrynodes.c            |  8 ++--
 src/or/entrynodes.h            | 21 +++++++--
 src/or/ext_orport.c            |  2 +-
 src/or/ext_orport.h            |  6 ++-
 src/or/fp_pair.c               |  2 +-
 src/or/fp_pair.h               |  7 ++-
 src/or/geoip.c                 |  5 ++-
 src/or/hs_cache.c              | 44 ++++++++++++-------
 src/or/hs_circuitmap.c         |  5 ++-
 src/or/hs_common.c             |  2 +-
 src/or/hs_common.h             |  4 +-
 src/or/hs_descriptor.c         | 10 ++---
 src/or/hs_descriptor.h         | 21 ++++++---
 src/or/hs_ident.c              |  6 +--
 src/or/hs_ident.h              | 12 ++++--
 src/or/hs_service.c            | 12 +++---
 src/or/hs_service.h            | 23 ++++++----
 src/or/microdesc.h             |  6 ++-
 src/or/networkstatus.c         |  8 ++--
 src/or/networkstatus.h         | 16 +++++--
 src/or/nodelist.c              |  6 ++-
 src/or/onion.c                 |  2 +-
 src/or/onion.h                 |  4 +-
 src/or/onion_fast.c            |  2 +-
 src/or/onion_fast.h            |  4 +-
 src/or/onion_ntor.c            |  2 +-
 src/or/onion_ntor.h            |  4 +-
 src/or/policies.c              | 10 ++---
 src/or/policies.h              | 12 ++++--
 src/or/proto_socks.c           |  2 +-
 src/or/proto_socks.h           |  4 +-
 src/or/protover.c              |  2 +-
 src/or/protover.h              |  4 +-
 src/or/relay.c                 |  4 +-
 src/or/relay.h                 |  8 +++-
 src/or/rendcache.c             | 32 +++++++-------
 src/or/rendcache.h             | 18 +++++---
 src/or/rendclient.c            | 14 +++---
 src/or/rendcommon.c            |  6 +--
 src/or/rendcommon.h            | 14 ++++--
 src/or/rendservice.c           | 18 ++++----
 src/or/rendservice.h           | 22 +++++++---
 src/or/rephist.c               | 20 ++++++---
 src/or/replaycache.c           |  2 +-
 src/or/replaycache.h           |  4 +-
 src/or/router.c                |  3 +-
 src/or/router.h                |  4 +-
 src/or/routerlist.c            | 40 ++++++++++++------
 src/or/routerlist.h            | 14 ++++--
 src/or/routerset.c             |  2 +-
 src/or/routerset.h             |  3 +-
 src/or/scheduler_kist.c        |  4 +-
 src/or/shared_random.c         |  4 +-
 src/or/shared_random.h         |  3 +-
 src/or/shared_random_state.c   | 14 ++++--
 src/or/shared_random_state.h   |  2 +-
 src/or/statefile.c             |  2 +-
 src/or/statefile.h             |  3 +-
 src/or/torcert.c               |  4 +-
 src/or/torcert.h               |  7 ++-
 src/or/transports.c            |  2 +-
 src/or/transports.h            |  3 +-
 src/test/test-timers.c         |  2 +-
 src/test/test.c                |  6 +--
 src/test/test_address.c        | 16 +++----
 src/test/test_cell_queue.c     |  4 +-
 src/test/test_channel.c        |  2 +-
 src/test/test_circuitlist.c    | 28 ++++++------
 src/test/test_dir.c            |  6 +--
 src/test/test_dir_handle_get.c | 96 +++++++++++++++++++++---------------------
 src/test/test_dns.c            |  6 +--
 src/test/test_entryconn.c      | 34 +++++++--------
 src/test/test_entrynodes.c     |  4 +-
 src/test/test_extorport.c      | 10 ++---
 src/test/test_handles.c        |  2 +
 src/test/test_hs_cache.c       |  2 +-
 src/test/test_hs_client.c      | 12 +++---
 src/test/test_hs_intropoint.c  | 38 ++++++++---------
 src/test/test_hs_service.c     | 16 +++----
 src/test/test_link_handshake.c | 14 +++---
 src/test/test_oom.c            |  2 +-
 src/test/test_policy.c         |  8 ++--
 src/test/test_rendcache.c      |  8 ++--
 src/test/test_replay.c         |  2 +-
 src/test/test_routerlist.c     |  2 +-
 src/test/test_routerset.c      | 56 ++++++++++++------------
 src/test/test_shared_random.c  |  2 +-
 169 files changed, 976 insertions(+), 555 deletions(-)

diff --cc src/or/channel.c
index 5b9d860ba,90536b146..7fa976817
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@@ -159,15 -202,39 +160,15 @@@ HT_PROTOTYPE(channel_idmap, channel_idm
  HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
               channel_idmap_eq, 0.5,  tor_reallocarray_, tor_free_)
  
 -static cell_queue_entry_t * cell_queue_entry_dup(cell_queue_entry_t *q);
 -#if 0
 -static int cell_queue_entry_is_padding(cell_queue_entry_t *q);
 -#endif
 -static cell_queue_entry_t *
 -cell_queue_entry_new_fixed(cell_t *cell);
 -static cell_queue_entry_t *
 -cell_queue_entry_new_var(var_cell_t *var_cell);
 -static int is_destroy_cell(channel_t *chan,
 -                           const cell_queue_entry_t *q, circid_t *circid_out);
 -
 -static void channel_assert_counter_consistency(void);
 -
  /* Functions to maintain the digest map */
 -static void channel_add_to_digest_map(channel_t *chan);
  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);
 -/*
 - * Flush cells from just the outgoing queue without trying to get them
 - * from circuits; used internall by channel_flush_some_cells().
 - */
 -static ssize_t
 -channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
 -                                             ssize_t num_cells);
+ static void channel_force_xfree(channel_t *chan);
 -static void channel_free_list(smartlist_t *channels, int mark_for_close);
++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);
++                                        int mark_for_close);
+ static void channel_listener_force_xfree(channel_listener_t *chan_l);
 -static size_t channel_get_cell_queue_entry_size(channel_t *chan,
 -                                                cell_queue_entry_t *q);
 -static void
 -channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q);
  
  /***********************************
   * Channel state utility functions *
@@@ -962,8 -1067,9 +963,8 @@@ channel_listener_free_(channel_listener
   */
  
  static void
- channel_force_free(channel_t *chan)
+ channel_force_xfree(channel_t *chan)
  {
 -  cell_queue_entry_t *cell, *cell_tmp;
    tor_assert(chan);
  
    log_debug(LD_CHANNEL,
@@@ -1429,18 -1668,250 +1430,17 @@@ channel_clear_remote_end(channel_t *cha
  }
  
  /**
 - * Set the remote end metadata (identity_digest/nickname) of a channel
 + * Write to a channel the given packed cell.
   *
-  * Return 0 on success or -1 on error.
 - * This function sets new remote end info on a channel; this is intended
 - * for use by the lower layer.
 - */
 -
 -void
 -channel_set_remote_end(channel_t *chan,
 -                       const char *identity_digest,
 -                       const char *nickname)
 -{
 -  int was_in_digest_map, should_be_in_digest_map, state_not_in_map;
 -
 -  tor_assert(chan);
 -
 -  log_debug(LD_CHANNEL,
 -            "Setting remote endpoint identity on channel %p with "
 -            "global ID " U64_FORMAT " to nickname %s, digest %s",
 -            chan, U64_PRINTF_ARG(chan->global_identifier),
 -            nickname ? nickname : "(null)",
 -            identity_digest ?
 -              hex_str(identity_digest, DIGEST_LEN) : "(null)");
 -
 -  state_not_in_map = CHANNEL_CONDEMNED(chan);
 -
 -  was_in_digest_map =
 -    !state_not_in_map &&
 -    chan->registered &&
 -    !tor_digest_is_zero(chan->identity_digest);
 -  should_be_in_digest_map =
 -    !state_not_in_map &&
 -    chan->registered &&
 -    (identity_digest &&
 -     !tor_digest_is_zero(identity_digest));
 -
 -  if (was_in_digest_map)
 -    /* We should always remove it; we'll add it back if we're writing
 -     * in a new digest.
 -     */
 -    channel_remove_from_digest_map(chan);
 -
 -  if (identity_digest) {
 -    memcpy(chan->identity_digest,
 -           identity_digest,
 -           sizeof(chan->identity_digest));
 -
 -  } else {
 -    memset(chan->identity_digest, 0,
 -           sizeof(chan->identity_digest));
 -  }
 -
 -  tor_free(chan->nickname);
 -  if (nickname)
 -    chan->nickname = tor_strdup(nickname);
 -
 -  /* Put it in the digest map if we should */
 -  if (should_be_in_digest_map)
 -    channel_add_to_digest_map(chan);
 -}
 -
 -/**
 - * Duplicate a cell queue entry; this is a shallow copy intended for use
 - * in channel_write_cell_queue_entry().
 - */
 -
 -static cell_queue_entry_t *
 -cell_queue_entry_dup(cell_queue_entry_t *q)
 -{
 -  cell_queue_entry_t *rv = NULL;
 -
 -  tor_assert(q);
 -
 -  rv = tor_malloc(sizeof(*rv));
 -  memcpy(rv, q, sizeof(*rv));
 -
 -  return rv;
 -}
 -
 -/**
 - * Free a cell_queue_entry_t; the handed_off parameter indicates whether
 - * the contents were passed to the lower layer (it is responsible for
 - * them) or not (we should free).
 - */
 -
 -STATIC void
 -cell_queue_entry_xfree(cell_queue_entry_t *q, int handed_off)
 -{
 -  if (!q) return;
 -
 -  if (!handed_off) {
 -    /*
 -     * If we handed it off, the recipient becomes responsible (or
 -     * with packed cells the channel_t subclass calls packed_cell
 -     * free after writing out its contents; see, e.g.,
 -     * channel_tls_write_packed_cell_method().  Otherwise, we have
 -     * to take care of it here if possible.
 -     */
 -    switch (q->type) {
 -      case CELL_QUEUE_FIXED:
 -        if (q->u.fixed.cell) {
 -          /*
 -           * There doesn't seem to be a cell_free() function anywhere in the
 -           * pre-channel code; just use tor_free()
 -           */
 -          tor_free(q->u.fixed.cell);
 -        }
 -        break;
 -      case CELL_QUEUE_PACKED:
 -        if (q->u.packed.packed_cell) {
 -          packed_cell_free(q->u.packed.packed_cell);
 -        }
 -        break;
 -      case CELL_QUEUE_VAR:
 -        if (q->u.var.var_cell) {
 -          /*
 -           * This one's in connection_or.c; it'd be nice to figure out the
 -           * whole flow of cells from one end to the other and factor the
 -           * cell memory management functions like this out of the specific
 -           * TLS lower layer.
 -           */
 -          var_cell_free(q->u.var.var_cell);
 -        }
 -        break;
 -      default:
 -        /*
 -         * Nothing we can do if we don't know the type; this will
 -         * have been warned about elsewhere.
 -         */
 -        break;
 -    }
 -  }
 -  tor_free(q);
 -}
 -
 -#if 0
 -/**
 - * Check whether a cell queue entry is padding; this is a helper function
 - * for channel_write_cell_queue_entry()
 - */
 -
 -static int
 -cell_queue_entry_is_padding(cell_queue_entry_t *q)
 -{
 -  tor_assert(q);
 -
 -  if (q->type == CELL_QUEUE_FIXED) {
 -    if (q->u.fixed.cell) {
 -      if (q->u.fixed.cell->command == CELL_PADDING ||
 -          q->u.fixed.cell->command == CELL_VPADDING) {
 -        return 1;
 -      }
 -    }
 -  } else if (q->type == CELL_QUEUE_VAR) {
 -    if (q->u.var.var_cell) {
 -      if (q->u.var.var_cell->command == CELL_PADDING ||
 -          q->u.var.var_cell->command == CELL_VPADDING) {
 -        return 1;
 -      }
 -    }
 -  }
 -
 -  return 0;
 -}
 -#endif /* 0 */
 -
 -/**
 - * Allocate a new cell queue entry for a fixed-size cell
 - */
 -
 -static cell_queue_entry_t *
 -cell_queue_entry_new_fixed(cell_t *cell)
 -{
 -  cell_queue_entry_t *q = NULL;
 -
 -  tor_assert(cell);
 -
 -  q = tor_malloc(sizeof(*q));
 -  q->type = CELL_QUEUE_FIXED;
 -  q->u.fixed.cell = cell;
 -
 -  return q;
 -}
 -
 -/**
 - * Allocate a new cell queue entry for a variable-size cell
 - */
 -
 -static cell_queue_entry_t *
 -cell_queue_entry_new_var(var_cell_t *var_cell)
 -{
 -  cell_queue_entry_t *q = NULL;
 -
 -  tor_assert(var_cell);
 -
 -  q = tor_malloc(sizeof(*q));
 -  q->type = CELL_QUEUE_VAR;
 -  q->u.var.var_cell = var_cell;
 -
 -  return q;
 -}
 -
 -/**
 - * Ask how big the cell contained in a cell_queue_entry_t is
 - */
 -
 -static size_t
 -channel_get_cell_queue_entry_size(channel_t *chan, cell_queue_entry_t *q)
 -{
 -  size_t rv = 0;
 -
 -  tor_assert(chan);
 -  tor_assert(q);
 -
 -  switch (q->type) {
 -    case CELL_QUEUE_FIXED:
 -      rv = get_cell_network_size(chan->wide_circ_ids);
 -      break;
 -    case CELL_QUEUE_VAR:
 -      rv = get_var_cell_header_size(chan->wide_circ_ids) +
 -           (q->u.var.var_cell ? q->u.var.var_cell->payload_len : 0);
 -      break;
 -    case CELL_QUEUE_PACKED:
 -      rv = get_cell_network_size(chan->wide_circ_ids);
 -      break;
 -    default:
 -      tor_assert_nonfatal_unreached_once();
 -  }
 -
 -  return rv;
 -}
 -
 -/**
 - * Write to a channel based on a cell_queue_entry_t
   *
 - * Given a cell_queue_entry_t filled out by the caller, try to send the cell
 - * and queue it if we can't.
 + * 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
 + * the caller responsability to free the cell.
   */
 -
 -static void
 -channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
 +static int
 +write_packed_cell(channel_t *chan, packed_cell_t *cell)
  {
 -  int result = 0, sent = 0;
 -  cell_queue_entry_t *tmp = NULL;
 +  int ret = -1;
    size_t cell_bytes;
  
    tor_assert(chan);
diff --cc src/or/channel.h
index d88a77c9a,909813cee..0f685011a
--- a/src/or/channel.h
+++ b/src/or/channel.h
@@@ -457,9 -511,16 +457,12 @@@ void channel_close_from_lower_layer(cha
  void channel_close_for_error(channel_t *chan);
  void channel_closed(channel_t *chan);
  
 -void channel_listener_close_from_lower_layer(channel_listener_t *chan_l);
 -void channel_listener_close_for_error(channel_listener_t *chan_l);
 -void channel_listener_closed(channel_listener_t *chan_l);
 -
  /* 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 */
  
diff --cc src/or/protover.h
index 83a728e62,2539c92c3..8bbc2fc71
--- a/src/or/protover.h
+++ b/src/or/protover.h
@@@ -82,10 -82,11 +82,12 @@@ STATIC smartlist_t *parse_protocol_list
  STATIC char *encode_protocol_list(const smartlist_t *sl);
  STATIC const char *protocol_type_to_str(protocol_type_t pr);
  STATIC int str_to_protocol_type(const char *s, protocol_type_t *pr_out);
- STATIC void proto_entry_free(proto_entry_t *entry);
+ STATIC void proto_entry_free_(proto_entry_t *entry);
 -#endif
+ #define proto_entry_free(entry) \
+   FREE_AND_NULL(proto_entry_t, proto_entry_free_, (entry))
  
 +#endif /* !defined(HAVE_RUST) && defined(TOR_UNIT_TESTS) */
 +
  #endif /* defined(PROTOVER_PRIVATE) */
  
  #endif /* !defined(TOR_PROTOVER_H) */
diff --cc src/or/rendservice.h
index 15badce6a,70ebd8786..88da7b866
--- a/src/or/rendservice.h
+++ b/src/or/rendservice.h
@@@ -183,11 -189,26 +189,17 @@@ void rend_service_init(void)
  rend_service_port_config_t *rend_service_parse_port_config(const char *string,
                                                             const char *sep,
                                                             char **err_msg_out);
- void rend_service_port_config_free(rend_service_port_config_t *p);
- 
- void rend_authorized_client_free(rend_authorized_client_t *client);
+ void rend_service_port_config_free_(rend_service_port_config_t *p);
+ #define rend_service_port_config_free(p) \
+   FREE_AND_NULL(rend_service_port_config_t, rend_service_port_config_free_, \
+                 (p))
+ 
+ void rend_authorized_client_free_(rend_authorized_client_t *client);
+ #define rend_authorized_client_free(client) \
+   FREE_AND_NULL(rend_authorized_client_t, rend_authorized_client_free_, \
+                 (client))
  
 -/** Return value from rend_service_add_ephemeral. */
 -typedef enum {
 -  RSAE_BADAUTH = -5, /**< Invalid auth_type/auth_clients */
 -  RSAE_BADVIRTPORT = -4, /**< Invalid VIRTPORT/TARGET(s) */
 -  RSAE_ADDREXISTS = -3, /**< Onion address collision */
 -  RSAE_BADPRIVKEY = -2, /**< Invalid public key */
 -  RSAE_INTERNAL = -1, /**< Internal error */
 -  RSAE_OKAY = 0 /**< Service added as expected */
 -} rend_service_add_ephemeral_status_t;
 -rend_service_add_ephemeral_status_t rend_service_add_ephemeral(crypto_pk_t *pk,
 +hs_service_add_ephemeral_status_t rend_service_add_ephemeral(crypto_pk_t *pk,
                                 smartlist_t *ports,
                                 int max_streams_per_circuit,
                                 int max_streams_close_circuit,
diff --cc src/test/test_channel.c
index 38b69a9ad,594372693..55d43a04e
--- a/src/test/test_channel.c
+++ b/src/test/test_channel.c
@@@ -523,162 -640,152 +523,162 @@@ test_channel_dumpstats(void *arg
    return;
  }
  
 +/* Test outbound cell. The callstack is:
 + *  channel_flush_some_cells()
 + *   -> channel_flush_from_first_active_circuit()
 + *     -> channel_write_packed_cell()
 + *       -> write_packed_cell()
 + *         -> chan->write_packed_cell() fct ptr.
 + *
 + * This test goes from a cell in a circuit up to the channel write handler
 + * that should put them on the connection outbuf. */
  static void
 -test_channel_flush(void *arg)
 +test_channel_outbound_cell(void *arg)
  {
 -  channel_t *ch = NULL;
 -  cell_t *cell = NULL;
 -  packed_cell_t *p_cell = NULL;
 -  var_cell_t *v_cell = NULL;
 -  int init_count;
 -
 -  (void)arg;
 +  int old_count;
 +  channel_t *chan = NULL;
 +  packed_cell_t *p_cell = NULL, *p_cell2 = NULL;
 +  origin_circuit_t *circ = NULL;
 +  cell_queue_t *queue;
  
 -  ch = new_fake_channel();
 -  tt_assert(ch);
 +  (void) arg;
  
 -  /* Cache the original count */
 -  init_count = test_cells_written;
 +  /* The channel will be freed so we need to hijack this so the scheduler
 +   * doesn't get confused. */
 +  MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  
 -  /* Stop accepting so we can queue some */
 -  test_chan_accept_cells = 0;
 +  /* Accept cells to lower layer */
 +  test_chan_accept_cells = 1;
  
 -  /* Queue a regular cell */
 -  cell = tor_malloc_zero(sizeof(cell_t));
 -  make_fake_cell(cell);
 -  channel_write_cell(ch, cell);
 -  /* It should be queued, so assert that we didn't write it */
 -  tt_int_op(test_cells_written, OP_EQ, init_count);
 -
 -  /* Queue a var cell */
 -  v_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
 -  make_fake_var_cell(v_cell);
 -  channel_write_var_cell(ch, v_cell);
 -  /* It should be queued, so assert that we didn't write it */
 -  tt_int_op(test_cells_written, OP_EQ, init_count);
 -
 -  /* Try a packed cell now */
 +  /* Setup a valid circuit to queue a cell. */
 +  circ = origin_circuit_new();
 +  tt_assert(circ);
 +  /* Circuit needs an origin purpose to be considered origin. */
 +  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_GENERAL;
 +  TO_CIRCUIT(circ)->n_circ_id = 42;
 +  /* This is the outbound test so use the next channel queue. */
 +  queue = &TO_CIRCUIT(circ)->n_chan_cells;
 +  /* Setup packed cell to queue on the circuit. */
    p_cell = packed_cell_new();
    tt_assert(p_cell);
 -  channel_write_packed_cell(ch, p_cell);
 -  /* It should be queued, so assert that we didn't write it */
 -  tt_int_op(test_cells_written, OP_EQ, init_count);
 -
 -  /* Now allow writes through again */
 -  test_chan_accept_cells = 1;
 -
 -  /* ...and flush */
 -  channel_flush_cells(ch);
 -
 -  /* All three should have gone through */
 -  tt_int_op(test_cells_written, OP_EQ, init_count + 3);
 -
 - done:
 -  tor_free(ch);
 -
 -  return;
 -}
 -
 -/**
 - * Channel flush tests that require cmux mocking
 - */
 -
 -static void
 -test_channel_flushmux(void *arg)
 -{
 -  channel_t *ch = NULL;
 -  int old_count, q_len_before, q_len_after;
 -  ssize_t result;
 -
 -  (void)arg;
 -
 -  /* Install mocks we need for this test */
 -  MOCK(channel_flush_from_first_active_circuit,
 -       chan_test_channel_flush_from_first_active_circuit_mock);
 -  MOCK(circuitmux_num_cells,
 -       chan_test_circuitmux_num_cells_mock);
 -
 -  ch = new_fake_channel();
 -  tt_assert(ch);
 -  ch->cmux = circuitmux_alloc();
 -
 +  p_cell2 = packed_cell_new();
 +  tt_assert(p_cell2);
 +  /* Setup a channel to put the circuit on. */
 +  chan = new_fake_channel();
 +  tt_assert(chan);
 +  chan->state = CHANNEL_STATE_OPENING;
 +  channel_change_state_open(chan);
 +  /* Outbound channel. */
 +  channel_mark_outgoing(chan);
 +  /* Try to register it so we can clean it through the channel cleanup
 +   * process. */
 +  channel_register(chan);
 +  tt_int_op(chan->registered, OP_EQ, 1);
 +  /* Set EWMA policy so we can pick it when flushing. */
 +  channel_set_cmux_policy_everywhere(&ewma_policy);
 +  tt_ptr_op(circuitmux_get_policy(chan->cmux), OP_EQ, &ewma_policy);
 +
 +  /* Register circuit to the channel circid map which will attach the circuit
 +   * to the channel's cmux as well. */
 +  circuit_set_n_circid_chan(TO_CIRCUIT(circ), 42, chan);
 +  tt_int_op(channel_num_circuits(chan), OP_EQ, 1);
 +  tt_assert(!TO_CIRCUIT(circ)->next_active_on_n_chan);
 +  tt_assert(!TO_CIRCUIT(circ)->prev_active_on_n_chan);
 +  /* Test the cmux state. */
 +  tt_ptr_op(TO_CIRCUIT(circ)->n_mux, OP_EQ, chan->cmux);
 +  tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 1);
 +
 +  /* Flush the channel without any cell on it. */
    old_count = test_cells_written;
 -
 -  test_target_cmux = ch->cmux;
 -  test_cmux_cells = 1;
 -
 -  /* Enable cell acceptance */
 -  test_chan_accept_cells = 1;
 -
 -  result = channel_flush_some_cells(ch, 1);
 -
 -  tt_int_op(result, OP_EQ, 1);
 +  ssize_t flushed = channel_flush_some_cells(chan, 1);
 +  tt_i64_op(flushed, OP_EQ, 0);
 +  tt_int_op(test_cells_written, OP_EQ, old_count);
 +  tt_int_op(channel_more_to_flush(chan), OP_EQ, 0);
 +  tt_int_op(circuitmux_num_active_circuits(chan->cmux), OP_EQ, 0);
 +  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 0);
 +  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 0);
 +  tt_u64_op(chan->n_cells_xmitted, OP_EQ, 0);
 +  tt_u64_op(chan->n_bytes_xmitted, OP_EQ, 0);
 +
 +  /* Queue cell onto the next queue that is the outbound direction. Than
 +   * update its cmux so the circuit can be picked when flushing cells. */
 +  cell_queue_append(queue, p_cell);
 +  p_cell = NULL;
 +  tt_int_op(queue->n, OP_EQ, 1);
 +  cell_queue_append(queue, p_cell2);
 +  p_cell2 = NULL;
 +  tt_int_op(queue->n, OP_EQ, 2);
 +
 +  update_circuit_on_cmux(TO_CIRCUIT(circ), CELL_DIRECTION_OUT);
 +  tt_int_op(circuitmux_num_active_circuits(chan->cmux), OP_EQ, 1);
 +  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 2);
 +  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 1);
 +
 +  /* From this point on, we have a queued cell on an active circuit attached
 +   * to the channel's cmux. */
 +
 +  /* Flush the first cell. This is going to go down the call stack. */
 +  old_count = test_cells_written;
 +  flushed = channel_flush_some_cells(chan, 1);
 +  tt_i64_op(flushed, OP_EQ, 1);
    tt_int_op(test_cells_written, OP_EQ, old_count + 1);
 -  tt_int_op(test_cmux_cells, OP_EQ, 0);
 -
 -  /* Now try it without accepting to force them into the queue */
 -  test_chan_accept_cells = 0;
 -  test_cmux_cells = 1;
 -  q_len_before = chan_cell_queue_len(&(ch->outgoing_queue));
 -
 -  result = channel_flush_some_cells(ch, 1);
 -
 -  /* We should not have actually flushed any */
 -  tt_int_op(result, OP_EQ, 0);
 +  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 1);
 +  tt_int_op(channel_more_to_flush(chan), OP_EQ, 1);
 +  /* Circuit should remain active because there is a second cell queued. */
 +  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 1);
 +  /* Should still be attached. */
 +  tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 1);
 +  tt_u64_op(chan->n_cells_xmitted, OP_EQ, 1);
 +  tt_u64_op(chan->n_bytes_xmitted, OP_EQ, get_cell_network_size(0));
 +
 +  /* Flush second cell. This is going to go down the call stack. */
 +  old_count = test_cells_written;
 +  flushed = channel_flush_some_cells(chan, 1);
 +  tt_i64_op(flushed, OP_EQ, 1);
    tt_int_op(test_cells_written, OP_EQ, old_count + 1);
 -  /* But we should have gotten to the fake cellgen loop */
 -  tt_int_op(test_cmux_cells, OP_EQ, 0);
 -  /* ...and we should have a queued cell */
 -  q_len_after = chan_cell_queue_len(&(ch->outgoing_queue));
 -  tt_int_op(q_len_after, OP_EQ, q_len_before + 1);
 -
 -  /* Now accept cells again and drain the queue */
 -  test_chan_accept_cells = 1;
 -  channel_flush_cells(ch);
 -  tt_int_op(test_cells_written, OP_EQ, old_count + 2);
 -  tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
 -
 -  test_target_cmux = NULL;
 -  test_cmux_cells = 0;
 +  tt_int_op(circuitmux_num_cells(chan->cmux), OP_EQ, 0);
 +  tt_int_op(channel_more_to_flush(chan), OP_EQ, 0);
 +  /* No more cells should make the circuit inactive. */
 +  tt_int_op(circuitmux_is_circuit_active(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 0);
 +  /* Should still be attached. */
 +  tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
 +            OP_EQ, 1);
 +  tt_u64_op(chan->n_cells_xmitted, OP_EQ, 2);
 +  tt_u64_op(chan->n_bytes_xmitted, OP_EQ, get_cell_network_size(0) * 2);
  
   done:
 -  if (ch)
 -    circuitmux_free(ch->cmux);
 -  tor_free(ch);
 -
 -  UNMOCK(channel_flush_from_first_active_circuit);
 -  UNMOCK(circuitmux_num_cells);
 -
 -  test_chan_accept_cells = 0;
 -
 -  return;
 +  if (circ) {
-     circuit_free(TO_CIRCUIT(circ));
++    circuit_free_(TO_CIRCUIT(circ));
 +  }
 +  tor_free(p_cell);
 +  channel_free_all();
 +  UNMOCK(scheduler_release_channel);
  }
  
 +/* Test inbound cell. The callstack is:
 + *  channel_process_cell()
 + *    -> chan->cell_handler()
 + *
 + * This test is about checking if we can process an inbound cell down to the
 + * channel handler. */
  static void
 -test_channel_incoming(void *arg)
 +test_channel_inbound_cell(void *arg)
  {
 -  channel_t *ch = NULL;
 +  channel_t *chan = NULL;
    cell_t *cell = NULL;
 -  var_cell_t *var_cell = NULL;
    int old_count;
  
 -  (void)arg;
 +  (void) arg;
  
 -  /* Mock these for duration of the test */
 -  MOCK(scheduler_channel_doesnt_want_writes,
 -       scheduler_channel_doesnt_want_writes_mock);
 -  MOCK(scheduler_release_channel,
 -       scheduler_release_channel_mock);
 +  /* The channel will be freed so we need to hijack this so the scheduler
 +   * doesn't get confused. */
 +  MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  
    /* Accept cells to lower layer */
    test_chan_accept_cells = 1;



More information about the tor-commits mailing list