⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rephist.c

📁 关于tor匿名通信的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    case REND_MID:
      n_rend_mid_ops++;
      break;
    case REND_SERVER:
      n_rend_server_ops++;
      break;
    default:
      log_warn(LD_BUG, "Unknown pk operation %d", operation);
  }
}

/** Log the number of times we've done each public/private-key operation. */
void
dump_pk_ops(int severity)
{
  log(severity, LD_GENERAL,
      "PK operations: %lu directory objects signed, "
      "%lu directory objects verified, "
      "%lu routerdescs signed, "
      "%lu routerdescs verified, "
      "%lu onionskins encrypted, "
      "%lu onionskins decrypted, "
      "%lu client-side TLS handshakes, "
      "%lu server-side TLS handshakes, "
      "%lu rendezvous client operations, "
      "%lu rendezvous middle operations, "
      "%lu rendezvous server operations.",
      (unsigned long) n_signed_dir_objs,
      (unsigned long) n_verified_dir_objs,
      (unsigned long) n_signed_routerdescs,
      (unsigned long) n_verified_routerdescs,
      (unsigned long) n_onionskins_encrypted,
      (unsigned long) n_onionskins_decrypted,
      (unsigned long) n_tls_client_handshakes,
      (unsigned long) n_tls_server_handshakes,
      (unsigned long) n_rend_client_ops,
      (unsigned long) n_rend_mid_ops,
      (unsigned long) n_rend_server_ops);
}

/** Free all storage held by the OR/link history caches, by the
 * bandwidth history arrays, or by the port history. */
void
rep_hist_free_all(void)
{
  digestmap_free(history_map, free_or_history);
  tor_free(read_array);
  tor_free(write_array);
  predicted_ports_free();
}

/****************** hidden service usage statistics ******************/

/** How large are the intervals for which we track and report hidden service
 * use? */
#define NUM_SECS_HS_USAGE_SUM_INTERVAL (15*60)
/** How far in the past do we remember and publish hidden service use? */
#define NUM_SECS_HS_USAGE_SUM_IS_VALID (24*60*60)
/** How many hidden service usage intervals do we remember? (derived) */
#define NUM_TOTALS_HS_USAGE (NUM_SECS_HS_USAGE_SUM_IS_VALID/ \
                             NUM_SECS_HS_USAGE_SUM_INTERVAL)

/** List element containing a service id and the count. */
typedef struct hs_usage_list_elem_t {
   /** Service id of this elem. */
  char service_id[REND_SERVICE_ID_LEN_BASE32+1];
  /** Number of occurrences for the given service id. */
  uint32_t count;
  /* Pointer to next list elem */
  struct hs_usage_list_elem_t *next;
} hs_usage_list_elem_t;

/** Ordered list that stores service ids and the number of observations. It is
 * ordered by the number of occurrences in descending order. Its purpose is to
 * calculate the frequency distribution when the period is over. */
typedef struct hs_usage_list_t {
  /* Pointer to the first element in the list. */
  hs_usage_list_elem_t *start;
  /* Number of total occurrences for all list elements. */
  uint32_t total_count;
  /* Number of service ids, i.e. number of list elements. */
  uint32_t total_service_ids;
} hs_usage_list_t;

/** Tracks service-related observations in the current period and their
 * history. */
typedef struct hs_usage_service_related_observation_t {
  /** Ordered list that stores service ids and the number of observations in
   * the current period. It is ordered by the number of occurrences in
   * descending order. Its purpose is to calculate the frequency distribution
   * when the period is over. */
  hs_usage_list_t *list;
  /** Circular arrays that store the history of observations. totals stores all
   * observations, twenty (ten, five) the number of observations related to a
   * service id being accounted for the top 20 (10, 5) percent of all
   * observations. */
  uint32_t totals[NUM_TOTALS_HS_USAGE];
  uint32_t five[NUM_TOTALS_HS_USAGE];
  uint32_t ten[NUM_TOTALS_HS_USAGE];
  uint32_t twenty[NUM_TOTALS_HS_USAGE];
} hs_usage_service_related_observation_t;

/** Tracks the history of general period-related observations, i.e. those that
 * cannot be related to a specific service id. */
typedef struct hs_usage_general_period_related_observations_t {
  /** Circular array that stores the history of observations. */
  uint32_t totals[NUM_TOTALS_HS_USAGE];
} hs_usage_general_period_related_observations_t;

/** Keeps information about the current observation period and its relation to
 * the histories of observations. */
typedef struct hs_usage_current_observation_period_t {
  /** Where do we write the next history entry? */
  int next_idx;
  /** How many values in history have been set ever? (upper bound!) */
  int num_set;
  /** When did this period begin? */
  time_t start_of_current_period;
  /** When does the next period begin? */
  time_t start_of_next_period;
} hs_usage_current_observation_period_t;

static hs_usage_current_observation_period_t *current_period = NULL;
static hs_usage_service_related_observation_t *publish_total = NULL;
static hs_usage_service_related_observation_t *publish_novel = NULL;
static hs_usage_service_related_observation_t *fetch_total = NULL;
static hs_usage_service_related_observation_t *fetch_successful = NULL;
static hs_usage_general_period_related_observations_t *descs = NULL;

/** Creates an empty ordered list element. */
static hs_usage_list_elem_t *
hs_usage_list_elem_new(void)
{
  hs_usage_list_elem_t *e;
  e = tor_malloc_zero(sizeof(hs_usage_list_elem_t));
  rephist_total_alloc += sizeof(hs_usage_list_elem_t);
  e->count = 1;
  e->next = NULL;
  return e;
}

/** Creates an empty ordered list. */
static hs_usage_list_t *
hs_usage_list_new(void)
{
  hs_usage_list_t *l;
  l = tor_malloc_zero(sizeof(hs_usage_list_t));
  rephist_total_alloc += sizeof(hs_usage_list_t);
  l->start = NULL;
  l->total_count = 0;
  l->total_service_ids = 0;
  return l;
}

/** Creates an empty structure for storing service-related observations. */
static hs_usage_service_related_observation_t *
hs_usage_service_related_observation_new(void)
{
  hs_usage_service_related_observation_t *h;
  h = tor_malloc_zero(sizeof(hs_usage_service_related_observation_t));
  rephist_total_alloc += sizeof(hs_usage_service_related_observation_t);
  h->list = hs_usage_list_new();
  return h;
}

/** Creates an empty structure for storing general period-related
 * observations. */
static hs_usage_general_period_related_observations_t *
hs_usage_general_period_related_observations_new(void)
{
  hs_usage_general_period_related_observations_t *p;
  p = tor_malloc_zero(sizeof(hs_usage_general_period_related_observations_t));
  rephist_total_alloc+= sizeof(hs_usage_general_period_related_observations_t);
  return p;
}

/** Creates an empty structure for storing period-specific information. */
static hs_usage_current_observation_period_t *
hs_usage_current_observation_period_new(void)
{
  hs_usage_current_observation_period_t *c;
  time_t now;
  c = tor_malloc_zero(sizeof(hs_usage_current_observation_period_t));
  rephist_total_alloc += sizeof(hs_usage_current_observation_period_t);
  now = time(NULL);
  c->start_of_current_period = now;
  c->start_of_next_period = now + NUM_SECS_HS_USAGE_SUM_INTERVAL;
  return c;
}

/** Initializes the structures for collecting hidden service usage data. */
static void
hs_usage_init(void)
{
  current_period = hs_usage_current_observation_period_new();
  publish_total = hs_usage_service_related_observation_new();
  publish_novel = hs_usage_service_related_observation_new();
  fetch_total = hs_usage_service_related_observation_new();
  fetch_successful = hs_usage_service_related_observation_new();
  descs = hs_usage_general_period_related_observations_new();
}

/** Clears the given ordered list by resetting its attributes and releasing
 * the memory allocated by its elements. */
static void
hs_usage_list_clear(hs_usage_list_t *lst)
{
  /* walk through elements and free memory */
  hs_usage_list_elem_t *current = lst->start;
  hs_usage_list_elem_t *tmp;
  while (current != NULL) {
    tmp = current->next;
    rephist_total_alloc -= sizeof(hs_usage_list_elem_t);
    tor_free(current);
    current = tmp;
  }
  /* reset attributes */
  lst->start = NULL;
  lst->total_count = 0;
  lst->total_service_ids = 0;
  return;
}

/** Frees the memory used by the given list. */
static void
hs_usage_list_free(hs_usage_list_t *lst)
{
  if (!lst)
    return;
  hs_usage_list_clear(lst);
  rephist_total_alloc -= sizeof(hs_usage_list_t);
  tor_free(lst);
}

/** Frees the memory used by the given service-related observations. */
static void
hs_usage_service_related_observation_free(
                                    hs_usage_service_related_observation_t *s)
{
  if (!s)
    return;
  hs_usage_list_free(s->list);
  rephist_total_alloc -= sizeof(hs_usage_service_related_observation_t);
  tor_free(s);
}

/** Frees the memory used by the given period-specific observations. */
static void
hs_usage_general_period_related_observations_free(
                             hs_usage_general_period_related_observations_t *s)
{
  rephist_total_alloc-=sizeof(hs_usage_general_period_related_observations_t);
  tor_free(s);
}

/** Frees the memory used by period-specific information. */
static void
hs_usage_current_observation_period_free(
                                    hs_usage_current_observation_period_t *s)
{
  rephist_total_alloc -= sizeof(hs_usage_current_observation_period_t);
  tor_free(s);
}

/** Frees all memory that was used for collecting hidden service usage data. */
void
hs_usage_free_all(void)
{
  hs_usage_general_period_related_observations_free(descs);
  descs = NULL;
  hs_usage_service_related_observation_free(fetch_successful);
  hs_usage_service_related_observation_free(fetch_total);
  hs_usage_service_related_observation_free(publish_novel);
  hs_usage_service_related_observation_free(publish_total);
  fetch_successful = fetch_total = publish_novel = publish_total = NULL;
  hs_usage_current_observation_period_free(current_period);
  current_period = NULL;
}

/** Inserts a new occurrence for the given service id to the given ordered
 * list. */
static void
hs_usage_insert_value(hs_usage_list_t *lst, const char *service_id)
{
  /* search if there is already an elem with same service_id in list */
  hs_usage_list_elem_t *current = lst->start;
  hs_usage_list_elem_t *previous = NULL;
  while (current != NULL && strcasecmp(current->service_id,service_id)) {
    previous = current;
    current = current->next;
  }
  /* found an element with same service_id? */
  if (current == NULL) {
    /* not found! append to end (which could also be the end of a zero-length
     * list), don't need to sort (1 is smallest value). */
    /* create elem */
    hs_usage_list_elem_t *e = hs_usage_list_elem_new();
    /* update list attributes (one new elem, one new occurrence) */
    lst->total_count++;
    lst->total_service_ids++;
    /* copy service id to elem */
    strlcpy(e->service_id,service_id,sizeof(e->service_id));
    /* let either l->start or previously last elem point to new elem */
    if (lst->start == NULL) {
      /* this is the first elem */
      lst->start = e;
    } else {
      /* there were elems in the list before */
      previous->next = e;
    }
  } else {
    /* found! add occurrence to elem and consider resorting */
    /* update list attributes (no new elem, but one new occurrence) */
    lst->total_count++;
    /* add occurrence to elem */
    current->count++;
    /* is it another than the first list elem? and has previous elem fewer
     * count than current? then we need to resort */
    if (previous != NULL && previous->count < current->count) {
      /* yes! we need to resort */
      /* remove current elem first */
      previous->next = current->next;
      /* can we prepend elem to all other elements? */
      if (lst->start->count <= current->count) {
        /* yes! prepend elem */
        current->next = lst->start;
        lst->start = current;
      } else {
        /* no! walk through list a second time and insert at correct place */
        hs_usage_list_elem_t *insert_current = lst->start->next;
        hs_usage_list_elem_t *insert_previous = lst->start;
        while (insert_current != NULL &&
               insert_current->count > current->count) {
          insert_previous = insert_current;
          insert_current = insert_current->next;
        }
        /* insert here */
        current->next = insert_current;
        insert_previous->next = current;
      }
    }
  }
}

/** Writes the current service-related observations to the history array and
 * clears the observations of the current period. */
static void
hs_usage_write_service_related_observations_to_history(
                                    hs_usage_current_observation_period_t *p,
                                    hs_usage_service_related_observation_t *h)
{
  /* walk through the first 20 % of list elements and calculate frequency
   * distributions */
  /* maximum indices for the three frequencies */
  int five_percent_idx = h->list->total_service_ids/20;
  int ten_percent_idx = h->list->total_service_ids/10;
  int twenty_percent_idx = h->list->total_service_ids/5;
  /* temp values */
  uint32_t five_percent = 0;
  uint32_t ten_percent = 0;
  uint32_t twenty_percent = 0;
  /* walk through list */
  hs_usage_list_elem_t *current = h->list->start;
  int i=0;
  while (current != NULL && i <= twenty_percent_idx) {
    twenty_percent += current->count;
    if (i <= ten_percent_idx)
      ten_percent += current->count;
    if (i <= five_percent_idx)
      five_percent += current->count;
    current = current->next;
    i++;
  }
  /* copy frequencies */
  h->twenty[p->next_idx] = twenty_percent;
  h->ten[p->next_idx] = ten_percent;
  h->five[p->next_idx] = five_percent;
  /* copy total number of observations */
  h->totals[p->next_idx] = h->list->total_count;
  /* free memory of old list */
  hs_usage_list_clear(h->list);
}

/** Advances to next observation period. */
static void
hs_usage_advance_current_observation_period(void)
{
  /* aggregate observations to history, including frequency distribution
   * arrays */
  hs_usage_write_service_related_observations_to_history(
                                    current_period, publish_total);
  hs_usage_write_service_related_observations_to_history(
                                    current_period, publish_novel);
  hs_usage_write_service_related_observations_to_history(
                                    current_period, fetch_total);
  hs_usage_write_service_related_observations_to_history(
                                    current_period, fetch_successful);
  /* write current number of descriptors to descs history */
  descs->totals[current_peri

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -