mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
Refactor geoip_get_dirreq_history() some more.
This patch avoids a bunch of allocations, and avoids using unallocated memory.
This commit is contained in:
parent
d4a75a222f
commit
b51c592547
@ -720,9 +720,9 @@ geoip_get_dirreq_history(geoip_client_action_t action,
|
|||||||
dirreq_type_t type)
|
dirreq_type_t type)
|
||||||
{
|
{
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
smartlist_t *dirreq_times = NULL;
|
smartlist_t *dirreq_completed = NULL;
|
||||||
uint32_t complete = 0, timeouts = 0, running = 0;
|
uint32_t complete = 0, timeouts = 0, running = 0;
|
||||||
int i = 0, bufsize = 1024, written;
|
int bufsize = 1024, written;
|
||||||
dirreq_map_entry_t **ptr, **next, *ent;
|
dirreq_map_entry_t **ptr, **next, *ent;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
@ -730,7 +730,7 @@ geoip_get_dirreq_history(geoip_client_action_t action,
|
|||||||
if (action != GEOIP_CLIENT_NETWORKSTATUS &&
|
if (action != GEOIP_CLIENT_NETWORKSTATUS &&
|
||||||
action != GEOIP_CLIENT_NETWORKSTATUS_V2)
|
action != GEOIP_CLIENT_NETWORKSTATUS_V2)
|
||||||
return NULL;
|
return NULL;
|
||||||
dirreq_times = smartlist_create();
|
dirreq_completed = smartlist_create();
|
||||||
for (ptr = HT_START(dirreqmap, &dirreq_map); ptr; ptr = next) {
|
for (ptr = HT_START(dirreqmap, &dirreq_map); ptr; ptr = next) {
|
||||||
ent = *ptr;
|
ent = *ptr;
|
||||||
if (ent->action != action || ent->type != type) {
|
if (ent->action != action || ent->type != type) {
|
||||||
@ -738,24 +738,17 @@ geoip_get_dirreq_history(geoip_client_action_t action,
|
|||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (ent->completed) {
|
if (ent->completed) {
|
||||||
uint32_t *bytes_per_second = tor_malloc_zero(sizeof(uint32_t));
|
smartlist_add(dirreq_completed, ent);
|
||||||
uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time,
|
|
||||||
&ent->completion_time);
|
|
||||||
if (time_diff == 0)
|
|
||||||
time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible
|
|
||||||
* by law of nature or something, but a milisecond
|
|
||||||
* is a bit greater than "instantly" */
|
|
||||||
*bytes_per_second = 1000 * ent->response_size / time_diff;
|
|
||||||
smartlist_add(dirreq_times, bytes_per_second);
|
|
||||||
complete++;
|
complete++;
|
||||||
|
next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr);
|
||||||
} else {
|
} else {
|
||||||
if (tv_mdiff(&ent->request_time, &now) / 1000 > DIRREQ_TIMEOUT)
|
if (tv_mdiff(&ent->request_time, &now) / 1000 > DIRREQ_TIMEOUT)
|
||||||
timeouts++;
|
timeouts++;
|
||||||
else
|
else
|
||||||
running++;
|
running++;
|
||||||
|
next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr);
|
||||||
|
tor_free(ent);
|
||||||
}
|
}
|
||||||
next = HT_NEXT_RMV(dirreqmap, &dirreq_map, ptr);
|
|
||||||
tor_free(ent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define DIR_REQ_GRANULARITY 4
|
#define DIR_REQ_GRANULARITY 4
|
||||||
@ -769,18 +762,29 @@ geoip_get_dirreq_history(geoip_client_action_t action,
|
|||||||
written = tor_snprintf(result, bufsize, "complete=%u,timeout=%u,"
|
written = tor_snprintf(result, bufsize, "complete=%u,timeout=%u,"
|
||||||
"running=%u", complete, timeouts, running);
|
"running=%u", complete, timeouts, running);
|
||||||
if (written < 0) {
|
if (written < 0) {
|
||||||
SMARTLIST_FOREACH(dirreq_times, uint32_t *, dlt, tor_free(dlt));
|
tor_free(result);
|
||||||
smartlist_free(dirreq_times);
|
goto done;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIN_DIR_REQ_RESPONSES 16
|
#define MIN_DIR_REQ_RESPONSES 16
|
||||||
if (complete >= MIN_DIR_REQ_RESPONSES) {
|
if (complete >= MIN_DIR_REQ_RESPONSES) {
|
||||||
uint32_t *dltimes = tor_malloc(sizeof(uint32_t) * complete);
|
uint32_t *dltimes;
|
||||||
SMARTLIST_FOREACH(dirreq_times, uint32_t *, dlt, {
|
/* We may have rounded 'completed' up. Here we want to use the
|
||||||
dltimes[i++] = *dlt;
|
* real value. */
|
||||||
tor_free(dlt);
|
complete = smartlist_len(dirreq_completed);
|
||||||
});
|
dltimes = tor_malloc_zero(sizeof(uint32_t) * complete);
|
||||||
median_uint32(dltimes, complete); /* sort */
|
SMARTLIST_FOREACH_BEGIN(dirreq_completed, dirreq_map_entry_t *, ent) {
|
||||||
|
uint32_t bytes_per_second;
|
||||||
|
uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time,
|
||||||
|
&ent->completion_time);
|
||||||
|
if (time_diff == 0)
|
||||||
|
time_diff = 1; /* Avoid DIV/0; "instant" answers are impossible
|
||||||
|
* by law of nature or something, but a milisecond
|
||||||
|
* is a bit greater than "instantly" */
|
||||||
|
bytes_per_second = 1000 * ent->response_size / time_diff;
|
||||||
|
dltimes[ent_sl_idx] = bytes_per_second;
|
||||||
|
} SMARTLIST_FOREACH_END(ent);
|
||||||
|
median_uint32(dltimes, complete); /* sorts as a side effect. */
|
||||||
written = tor_snprintf(result + written, bufsize - written,
|
written = tor_snprintf(result + written, bufsize - written,
|
||||||
",min=%u,d1=%u,d2=%u,q1=%u,d3=%u,d4=%u,md=%u,"
|
",min=%u,d1=%u,d2=%u,q1=%u,d3=%u,d4=%u,md=%u,"
|
||||||
"d6=%u,d7=%u,q3=%u,d8=%u,d9=%u,max=%u",
|
"d6=%u,d7=%u,q3=%u,d8=%u,d9=%u,max=%u",
|
||||||
@ -797,13 +801,14 @@ geoip_get_dirreq_history(geoip_client_action_t action,
|
|||||||
dltimes[8*complete/10-1],
|
dltimes[8*complete/10-1],
|
||||||
dltimes[9*complete/10-1],
|
dltimes[9*complete/10-1],
|
||||||
dltimes[complete-1]);
|
dltimes[complete-1]);
|
||||||
|
if (written<0)
|
||||||
|
tor_free(result);
|
||||||
tor_free(dltimes);
|
tor_free(dltimes);
|
||||||
} else {
|
|
||||||
SMARTLIST_FOREACH(dirreq_times, uint32_t *, dlt, tor_free(dlt));
|
|
||||||
}
|
}
|
||||||
if (written < 0)
|
done:
|
||||||
tor_free(result);
|
SMARTLIST_FOREACH(dirreq_completed, dirreq_map_entry_t *, ent,
|
||||||
smartlist_free(dirreq_times);
|
tor_free(ent));
|
||||||
|
smartlist_free(dirreq_completed);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user