Ticket #24119: 0001-Rewrite-channel_rsa_id_group_set_badness-with-ht-241.patch

File 0001-Rewrite-channel_rsa_id_group_set_badness-with-ht-241.patch, 7.9 KB (added by Hello71, 2 years ago)
  • src/or/channel.c

    From 108fd2457ae9569402fc1c335ad460a7aee4ec33 Mon Sep 17 00:00:00 2001
    From: "Alex Xu (Hello71)" <alex_y_xu@yahoo.ca>
    Date: Wed, 1 Nov 2017 19:17:50 +0000
    Subject: [PATCH] Rewrite channel_rsa_id_group_set_badness with ht, #24119
    
    ---
     src/or/channel.c       | 120 ++++++++++++++++++++++++++++++++++++-------------
     src/or/connection_or.c |  40 ++++++++++++-----
     src/or/connection_or.h |   1 +
     3 files changed, 118 insertions(+), 43 deletions(-)
    
    diff --git a/src/or/channel.c b/src/or/channel.c
    index 0b5a7fde9..88d702847 100644
    a b  
    6868#include "networkstatus.h"
    6969#include "rendservice.h"
    7070
     71typedef struct ed_identity_table_ent_s {
     72    HT_ENTRY(ed_identity_table_ent_s) node;
     73
     74    int n_or_conn;
     75
     76    ed25519_public_key_t *pubkey;
     77
     78    union {
     79        or_connection_t *or_conn;
     80        smartlist_t *or_conns;
     81    };
     82} ed_identity_table_ent_t;
     83
     84static uint32_t
     85ed_identity_hash(const ed_identity_table_ent_t *edid)
     86{
     87  uint32_t trunc_pubkey;
     88  memcpy(&trunc_pubkey, edid->pubkey, sizeof(trunc_pubkey));
     89  return trunc_pubkey;
     90}
     91
     92static unsigned
     93ed_identity_eq(const ed_identity_table_ent_t *a, const ed_identity_table_ent_t *b)
     94{
     95  return !memcmp(a->pubkey, b->pubkey, sizeof(*a->pubkey));
     96}
     97
     98typedef HT_HEAD(ed_identity_table_s, ed_identity_table_ent_s) ed_identity_table_t;
     99
     100HT_PROTOTYPE(ed_identity_table_s, ed_identity_table_ent_s, node, ed_identity_hash,
     101                     ed_identity_eq)
     102HT_GENERATE2(ed_identity_table_s, ed_identity_table_ent_s, node, ed_identity_hash,
     103                     ed_identity_eq, 0.6, tor_reallocarray, tor_free_)
     104
    71105/* Global lists of channels */
    72106
    73107/* All channel_t instances */
    channel_set_circid_type,(channel_t *chan, 
    47264760  }
    47274761}
    47284762
     4763/** Helper for channel_rsa_id_group_set_badness: Given the identity set, set
     4764 * the badness. */
     4765static int
     4766channel_rsa_id_group_set_badness_for_identity(ed_identity_table_ent_t *e, void *data)
     4767{
     4768  if (e->n_or_conn == 1) {
     4769    connection_or_expire_(time(NULL), e->or_conn, *(int *)data);
     4770  } else {
     4771    connection_or_group_set_badness_(e->or_conns, *(int *)data);
     4772    smartlist_free(e->or_conns);
     4773  }
     4774
     4775  tor_free(e);
     4776
     4777  return 1;
     4778}
     4779
    47294780/** Helper for channel_update_bad_for_new_circs(): Perform the
    47304781 * channel_update_bad_for_new_circs operation on all channels in <b>lst</b>,
    47314782 * all of which MUST have the same RSA ID.  (They MAY have different
    channel_rsa_id_group_set_badness(struct channel_list_s *lst, int force) 
    47364787  /*XXXX This function should really be about channels. 15056 */
    47374788  channel_t *chan;
    47384789
    4739   /* First, get a minimal list of the ed25519 identites */
    4740   smartlist_t *ed_identities = smartlist_new();
    4741   TOR_LIST_FOREACH(chan, lst, next_with_same_id) {
    4742     uint8_t *id_copy =
    4743       tor_memdup(&chan->ed25519_identity.pubkey, DIGEST256_LEN);
    4744     smartlist_add(ed_identities, id_copy);
    4745   }
    4746   smartlist_sort_digests256(ed_identities);
    4747   smartlist_uniq_digests256(ed_identities);
    4748 
    4749   /* Now, for each Ed identity, build a smartlist and find the best entry on
    4750    * it.  */
    4751   smartlist_t *or_conns = smartlist_new();
    4752   SMARTLIST_FOREACH_BEGIN(ed_identities, const uint8_t *, ed_id) {
    4753     TOR_LIST_FOREACH(chan, lst, next_with_same_id) {
    4754       channel_tls_t *chantls = BASE_CHAN_TO_TLS(chan);
    4755       if (tor_memneq(ed_id, &chan->ed25519_identity.pubkey, DIGEST256_LEN))
    4756         continue;
    4757       or_connection_t *orconn = chantls->conn;
    4758       if (orconn) {
    4759         tor_assert(orconn->chan == chantls);
    4760         smartlist_add(or_conns, orconn);
    4761       }
    4762     }
    4763 
    4764     connection_or_group_set_badness_(or_conns, force);
    4765     smartlist_clear(or_conns);
    4766   } SMARTLIST_FOREACH_END(ed_id);
     4790  if (PREDICT_UNLIKELY(TOR_LIST_EMPTY(lst)))
     4791    return;
    47674792
    47684793  /* XXXX 15056 we may want to do something special with connections that have
    47694794   * no set Ed25519 identity! */
    47704795
    4771   smartlist_free(or_conns);
     4796  ed_identity_table_t edids = HT_INITIALIZER();
     4797  TOR_LIST_FOREACH(chan, lst, next_with_same_id) {
     4798    channel_tls_t *chantls = BASE_CHAN_TO_TLS(chan);
     4799    or_connection_t *orconn = chantls->conn;
     4800    if (!orconn)
     4801      continue;
     4802
     4803    tor_assert(orconn->chan == chantls);
     4804
     4805    ed_identity_table_ent_t k;
     4806    k.pubkey = &chan->ed25519_identity;
     4807
     4808    ed_identity_table_ent_t *e = HT_FIND(ed_identity_table_s, &edids, &k);
     4809
     4810    if (e) {
     4811      if (e->n_or_conn == 1) {
     4812        smartlist_t *or_conns = smartlist_new();
     4813        smartlist_add(or_conns, e->or_conn);
     4814        e->or_conns = or_conns;
     4815        /* no need to keep numbers > 2 */
     4816        e->n_or_conn = 2;
     4817      }
     4818      smartlist_add(e->or_conns, orconn);
     4819    } else {
     4820      e = tor_malloc(sizeof(*e));
     4821      e->pubkey = k.pubkey;
     4822      e->n_or_conn = 1;
     4823      e->or_conn = orconn;
     4824      HT_INSERT(ed_identity_table_s, &edids, e);
     4825    }
     4826  }
     4827
     4828  HT_FOREACH_FN(ed_identity_table_s, &edids,
     4829                channel_rsa_id_group_set_badness_for_identity, &force);
    47724830
    4773   SMARTLIST_FOREACH(ed_identities, uint8_t *, ed_id, tor_free(ed_id));
    4774   smartlist_free(ed_identities);
     4831  /* free the hash table too */
     4832  HT_CLEAR(ed_identity_table_s, &edids);
    47754833}
    47764834
    47774835/** Go through all the channels (or if <b>digest</b> is non-NULL, just
  • src/or/connection_or.c

    diff --git a/src/or/connection_or.c b/src/or/connection_or.c
    index 9e3406360..f1d52db4a 100644
    a b connection_or_mark_bad_for_new_circs(or_connection_t *or_conn) 
    965965 * too old for new circuits? */
    966966#define TIME_BEFORE_OR_CONN_IS_TOO_OLD (60*60*24*7)
    967967
     968/** Expire an or_connection if it is too old. Helper for
     969 * connection_or_group_set_badness_.
     970 *
     971 * Returns 1 if the connection was already expired, else 0.
     972 */
     973int
     974connection_or_expire_(time_t now, or_connection_t *or_conn, int force)
     975{
     976  /* XXXX this function should also be about channels? */
     977  if (or_conn->base_.marked_for_close ||
     978      connection_or_is_bad_for_new_circs(or_conn))
     979    return 1;
     980
     981  if (force ||
     982      or_conn->base_.timestamp_created + TIME_BEFORE_OR_CONN_IS_TOO_OLD
     983        < now) {
     984    log_info(LD_OR,
     985             "Marking OR conn to %s:%d as too old for new circuits "
     986             "(fd "TOR_SOCKET_T_FORMAT", %d secs old).",
     987             or_conn->base_.address, or_conn->base_.port, or_conn->base_.s,
     988             (int)(now - or_conn->base_.timestamp_created));
     989    connection_or_mark_bad_for_new_circs(or_conn);
     990  }
     991
     992  return 0;
     993}
     994
    968995/** Given a list of all the or_connections with a given
    969996 * identity, set elements of that list as is_bad_for_new_circs as
    970997 * appropriate. Helper for connection_or_set_bad_connections().
    connection_or_group_set_badness_(smartlist_t *group, int force) 
    9951022  /* Pass 1: expire everything that's old, and see what the status of
    9961023   * everything else is. */
    9971024  SMARTLIST_FOREACH_BEGIN(group, or_connection_t *, or_conn) {
    998     if (or_conn->base_.marked_for_close ||
    999         connection_or_is_bad_for_new_circs(or_conn))
     1025    if (connection_or_expire_(now, or_conn, force))
    10001026      continue;
    1001     if (force ||
    1002         or_conn->base_.timestamp_created + TIME_BEFORE_OR_CONN_IS_TOO_OLD
    1003           < now) {
    1004       log_info(LD_OR,
    1005                "Marking OR conn to %s:%d as too old for new circuits "
    1006                "(fd "TOR_SOCKET_T_FORMAT", %d secs old).",
    1007                or_conn->base_.address, or_conn->base_.port, or_conn->base_.s,
    1008                (int)(now - or_conn->base_.timestamp_created));
    1009       connection_or_mark_bad_for_new_circs(or_conn);
    1010     }
    10111027
    10121028    if (connection_or_is_bad_for_new_circs(or_conn)) {
    10131029      ++n_old;
  • src/or/connection_or.h

    diff --git a/src/or/connection_or.h b/src/or/connection_or.h
    index ee66b7c52..4046be024 100644
    a b void var_cell_free(var_cell_t *cell); 
    112112#define MIN_LINK_PROTO_FOR_CHANNEL_PADDING 5
    113113#define MAX_LINK_PROTO MIN_LINK_PROTO_FOR_CHANNEL_PADDING
    114114
     115int connection_or_expire_(time_t now, or_connection_t *or_conn, int force);
    115116void connection_or_group_set_badness_(smartlist_t *group, int force);
    116117
    117118#ifdef TOR_UNIT_TESTS