📄 rephist.c
字号:
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 + -