aboutsummaryrefslogtreecommitdiff
path: root/src/or/geoip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/geoip.c')
-rw-r--r--src/or/geoip.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/src/or/geoip.c b/src/or/geoip.c
index a39366ed13..d59043a7f6 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2016, The Tor Project, Inc. */
+/* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -30,6 +30,7 @@
#define GEOIP_PRIVATE
#include "or.h"
#include "ht.h"
+#include "buffers.h"
#include "config.h"
#include "control.h"
#include "dnsserv.h"
@@ -149,7 +150,7 @@ geoip_add_entry(const tor_addr_t *low, const tor_addr_t *high,
idx = ((uintptr_t)idxplus1_)-1;
}
{
- geoip_country_t *c = smartlist_get(geoip_countries, idx);
+ geoip_country_t *c = smartlist_get(geoip_countries, (int)idx);
tor_assert(!strcasecmp(c->countrycode, country));
}
@@ -541,6 +542,9 @@ HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
HT_GENERATE2(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
+#define clientmap_entry_free(ent) \
+ FREE_AND_NULL(clientmap_entry_t, clientmap_entry_free_, ent)
+
/** Return the size of a client map entry. */
static inline size_t
clientmap_entry_size(const clientmap_entry_t *ent)
@@ -552,7 +556,7 @@ clientmap_entry_size(const clientmap_entry_t *ent)
/** Free all storage held by <b>ent</b>. */
static void
-clientmap_entry_free(clientmap_entry_t *ent)
+clientmap_entry_free_(clientmap_entry_t *ent)
{
if (!ent)
return;
@@ -624,8 +628,7 @@ geoip_note_client_seen(geoip_client_action_t action,
/* Only remember statistics if the DoS mitigation subsystem is enabled. If
* not, only if as entry guard or as bridge. */
if (!dos_enabled()) {
- if (!options->EntryStatistics &&
- (!(options->BridgeRelay && options->BridgeRecordUsageByCountry))) {
+ if (!options->EntryStatistics && !should_record_bridge_info(options)) {
return;
}
}
@@ -1017,7 +1020,7 @@ geoip_get_transport_history(void)
/* If it's the first time we see this transport, note it. */
if (val == 1)
- smartlist_add(transports_used, tor_strdup(transport_name));
+ smartlist_add_strdup(transports_used, transport_name);
log_debug(LD_GENERAL, "Client from '%s' with transport '%s'. "
"I've now seen %d clients.",
@@ -1067,9 +1070,9 @@ static char *
geoip_get_dirreq_history(dirreq_type_t type)
{
char *result = NULL;
+ buf_t *buf = NULL;
smartlist_t *dirreq_completed = NULL;
uint32_t complete = 0, timeouts = 0, running = 0;
- int bufsize = 1024, written;
dirreq_map_entry_t **ptr, **next;
struct timeval now;
@@ -1102,13 +1105,9 @@ geoip_get_dirreq_history(dirreq_type_t type)
DIR_REQ_GRANULARITY);
running = round_uint32_to_next_multiple_of(running,
DIR_REQ_GRANULARITY);
- result = tor_malloc_zero(bufsize);
- written = tor_snprintf(result, bufsize, "complete=%u,timeout=%u,"
- "running=%u", complete, timeouts, running);
- if (written < 0) {
- tor_free(result);
- goto done;
- }
+ buf = buf_new_with_capacity(1024);
+ buf_add_printf(buf, "complete=%u,timeout=%u,"
+ "running=%u", complete, timeouts, running);
#define MIN_DIR_REQ_RESPONSES 16
if (complete >= MIN_DIR_REQ_RESPONSES) {
@@ -1129,7 +1128,7 @@ geoip_get_dirreq_history(dirreq_type_t type)
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,
+ buf_add_printf(buf,
",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",
dltimes[0],
@@ -1145,14 +1144,15 @@ geoip_get_dirreq_history(dirreq_type_t type)
dltimes[8*complete/10-1],
dltimes[9*complete/10-1],
dltimes[complete-1]);
- if (written<0)
- tor_free(result);
tor_free(dltimes);
}
- done:
+
+ result = buf_extract(buf, NULL);
+
SMARTLIST_FOREACH(dirreq_completed, dirreq_map_entry_t *, ent,
tor_free(ent));
smartlist_free(dirreq_completed);
+ buf_free(buf);
return result;
}
@@ -1802,6 +1802,15 @@ getinfo_helper_geoip(control_connection_t *control_conn,
sa_family_t family;
tor_addr_t addr;
question += strlen("ip-to-country/");
+
+ if (!strcmp(question, "ipv4-available") ||
+ !strcmp(question, "ipv6-available")) {
+ family = !strcmp(question, "ipv4-available") ? AF_INET : AF_INET6;
+ const int available = geoip_is_loaded(family);
+ tor_asprintf(answer, "%d", !! available);
+ return 0;
+ }
+
family = tor_addr_parse(&addr, question);
if (family != AF_INET && family != AF_INET6) {
*errmsg = "Invalid address family";
@@ -1871,5 +1880,8 @@ geoip_free_all(void)
clear_geoip_db();
tor_free(bridge_stats_extrainfo);
+
+ memset(geoip_digest, 0, sizeof(geoip_digest));
+ memset(geoip6_digest, 0, sizeof(geoip6_digest));
}