aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.c20
-rw-r--r--src/ext/eventdns.c5
-rw-r--r--src/or/channeltls.c23
-rw-r--r--src/or/circuitlist.c164
-rw-r--r--src/or/circuitlist.h6
-rw-r--r--src/or/circuitstats.c12
-rw-r--r--src/or/connection_or.c6
-rwxr-xr-x[-rw-r--r--]src/or/control.c3
-rw-r--r--src/or/dirserv.c16
-rw-r--r--src/or/main.c13
-rw-r--r--src/or/main.h1
-rw-r--r--src/or/or.h36
-rw-r--r--src/or/policies.c23
-rw-r--r--src/or/reasons.c2
-rw-r--r--src/or/rendmid.c14
-rw-r--r--src/or/rendservice.c2
-rwxr-xr-x[-rw-r--r--]src/or/router.c71
-rw-r--r--src/or/router.h3
-rw-r--r--src/test/include.am1
-rw-r--r--src/test/test.c341
-rw-r--r--src/test/test_addr.c2
-rw-r--r--src/test/test_circuitlist.c90
-rw-r--r--src/test/test_policy.c432
-rw-r--r--src/test/test_util.c32
-rw-r--r--src/tools/tor-gencert.c3
25 files changed, 887 insertions, 434 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 135f2c9af..04c9d5923 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -560,21 +560,29 @@ tor_memmem(const void *_haystack, size_t hlen,
#else
/* This isn't as fast as the GLIBC implementation, but it doesn't need to
* be. */
- const char *p, *end;
+ const char *p, *last_possible_start;
const char *haystack = (const char*)_haystack;
const char *needle = (const char*)_needle;
char first;
tor_assert(nlen);
+ if (nlen > hlen)
+ return NULL;
+
p = haystack;
- end = haystack + hlen;
+ /* Last position at which the needle could start. */
+ last_possible_start = haystack + hlen - nlen;
first = *(const char*)needle;
- while ((p = memchr(p, first, end-p))) {
- if (p+nlen > end)
- return NULL;
+ while ((p = memchr(p, first, last_possible_start + 1 - p))) {
if (fast_memeq(p, needle, nlen))
return p;
- ++p;
+ if (++p > last_possible_start) {
+ /* This comparison shouldn't be necessary, since if p was previously
+ * equal to last_possible_start, the next memchr call would be
+ * "memchr(p, first, 0)", which will return NULL. But it clarifies the
+ * logic. */
+ return NULL;
+ }
}
return NULL;
#endif
diff --git a/src/ext/eventdns.c b/src/ext/eventdns.c
index 5ac9c1230..2b2988f1e 100644
--- a/src/ext/eventdns.c
+++ b/src/ext/eventdns.c
@@ -842,10 +842,11 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, size_t name_out_len
}
if (label_len > 63) return -1;
if (cp != name_out) {
- if (cp + 1 >= end) return -1;
+ if (cp >= name_out + name_out_len - 1) return -1;
*cp++ = '.';
}
- if (cp + label_len >= end) return -1;
+ if (label_len > name_out_len ||
+ cp >= name_out + name_out_len - label_len) return -1;
memcpy(cp, packet + j, label_len);
cp += label_len;
j += label_len;
diff --git a/src/or/channeltls.c b/src/or/channeltls.c
index 959ec4744..539ead193 100644
--- a/src/or/channeltls.c
+++ b/src/or/channeltls.c
@@ -1282,7 +1282,6 @@ static void
channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
{
int highest_supported_version = 0;
- const uint8_t *cp, *end;
int started_here = 0;
tor_assert(cell);
@@ -1322,11 +1321,15 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
}
tor_assert(chan->conn->handshake_state);
- end = cell->payload + cell->payload_len;
- for (cp = cell->payload; cp+1 < end; cp += 2) {
- uint16_t v = ntohs(get_uint16(cp));
- if (is_or_protocol_version_known(v) && v > highest_supported_version)
- highest_supported_version = v;
+
+ {
+ int i;
+ const uint8_t *cp = cell->payload;
+ for (i = 0; i < cell->payload_len / 2; ++i, cp += 2) {
+ uint16_t v = ntohs(get_uint16(cp));
+ if (is_or_protocol_version_known(v) && v > highest_supported_version)
+ highest_supported_version = v;
+ }
}
if (!highest_supported_version) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
@@ -1685,12 +1688,16 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
for (i = 0; i < n_certs; ++i) {
uint8_t cert_type;
uint16_t cert_len;
- if (ptr + 3 > cell->payload + cell->payload_len) {
+ if (cell->payload_len < 3)
+ goto truncated;
+ if (ptr > cell->payload + cell->payload_len - 3) {
goto truncated;
}
cert_type = *ptr;
cert_len = ntohs(get_uint16(ptr+1));
- if (ptr + 3 + cert_len > cell->payload + cell->payload_len) {
+ if (cell->payload_len < 3 + cert_len)
+ goto truncated;
+ if (ptr > cell->payload + cell->payload_len - cert_len - 3) {
goto truncated;
}
if (cert_type == OR_CERT_TYPE_TLS_LINK ||
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index b03b590aa..87270037c 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -32,6 +32,7 @@
#include "rephist.h"
#include "routerlist.h"
#include "routerset.h"
+
#include "ht.h"
/********* START VARIABLES **********/
@@ -45,6 +46,9 @@ static smartlist_t *circuits_pending_chans = NULL;
static void circuit_free_cpath_node(crypt_path_t *victim);
static void cpath_ref_decref(crypt_path_reference_t *cpath_ref);
+//static void circuit_set_rend_token(or_circuit_t *circ, int is_rend_circ,
+// const uint8_t *token);
+static void circuit_clear_rend_token(or_circuit_t *circ);
/********* END VARIABLES ************/
@@ -756,6 +760,8 @@ circuit_free(circuit_t *circ)
crypto_cipher_free(ocirc->n_crypto);
crypto_digest_free(ocirc->n_digest);
+ circuit_clear_rend_token(ocirc);
+
if (ocirc->rend_splice) {
or_circuit_t *other = ocirc->rend_splice;
tor_assert(other->base_.magic == OR_CIRCUIT_MAGIC);
@@ -1229,43 +1235,167 @@ circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
return NULL;
}
-/** Return the first OR circuit in the global list whose purpose is
- * <b>purpose</b>, and whose rend_token is the <b>len</b>-byte
- * <b>token</b>. */
+/** Map from rendezvous cookie to or_circuit_t */
+static digestmap_t *rend_cookie_map = NULL;
+
+/** Map from introduction point digest to or_circuit_t */
+static digestmap_t *intro_digest_map = NULL;
+
+/** Return the OR circuit whose purpose is <b>purpose</b>, and whose
+ * rend_token is the REND_TOKEN_LEN-byte <b>token</b>. If <b>is_rend_circ</b>,
+ * look for rendezvous point circuits; otherwise look for introduction point
+ * circuits. */
static or_circuit_t *
-circuit_get_by_rend_token_and_purpose(uint8_t purpose, const char *token,
- size_t len)
+circuit_get_by_rend_token_and_purpose(uint8_t purpose, int is_rend_circ,
+ const char *token)
{
- circuit_t *circ;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
- if (! circ->marked_for_close &&
- circ->purpose == purpose &&
- tor_memeq(TO_OR_CIRCUIT(circ)->rend_token, token, len))
- return TO_OR_CIRCUIT(circ);
+ or_circuit_t *circ;
+ digestmap_t *map = is_rend_circ ? rend_cookie_map : intro_digest_map;
+
+ if (!map)
+ return NULL;
+
+ circ = digestmap_get(map, token);
+ if (!circ ||
+ circ->base_.purpose != purpose ||
+ circ->base_.marked_for_close)
+ return NULL;
+
+ if (!circ->rendinfo ||
+ ! bool_eq(circ->rendinfo->is_rend_circ, is_rend_circ) ||
+ tor_memneq(circ->rendinfo->rend_token, token, REND_TOKEN_LEN)) {
+ char *t = tor_strdup(hex_str(token, REND_TOKEN_LEN));
+ log_warn(LD_BUG, "Wanted a circuit with %s:%d, but lookup returned %s:%d",
+ safe_str(t), is_rend_circ,
+ safe_str(hex_str(circ->rendinfo->rend_token, REND_TOKEN_LEN)),
+ (int)circ->rendinfo->is_rend_circ);
+ tor_free(t);
+ return NULL;
}
- return NULL;
+
+ return circ;
+}
+
+/** Clear the rendezvous cookie or introduction point key digest that's
+ * configured on <b>circ</b>, if any, and remove it from any such maps. */
+static void
+circuit_clear_rend_token(or_circuit_t *circ)
+{
+ or_circuit_t *found_circ;
+ digestmap_t *map;
+
+ if (!circ || !circ->rendinfo)
+ return;
+
+ map = circ->rendinfo->is_rend_circ ? rend_cookie_map : intro_digest_map;
+
+ if (!map) {
+ log_warn(LD_BUG, "Tried to clear rend token on circuit, but found no map");
+ return;
+ }
+
+ found_circ = digestmap_get(map, circ->rendinfo->rend_token);
+ if (found_circ == circ) {
+ /* Great, this is the right one. */
+ digestmap_remove(map, circ->rendinfo->rend_token);
+ } else if (found_circ) {
+ log_warn(LD_BUG, "Tried to clear rend token on circuit, but "
+ "it was already replaced in the map.");
+ } else {
+ log_warn(LD_BUG, "Tried to clear rend token on circuit, but "
+ "it not in the map at all.");
+ }
+
+ tor_free(circ->rendinfo); /* Sets it to NULL too */
+}
+
+/** Set the rendezvous cookie (if is_rend_circ), or the introduction point
+ * digest (if ! is_rend_circ) of <b>circ</b> to the REND_TOKEN_LEN-byte value
+ * in <b>token</b>, and add it to the appropriate map. If it previously had a
+ * token, clear it. If another circuit previously had the same
+ * cookie/intro-digest, mark that circuit and remove it from the map. */
+static void
+circuit_set_rend_token(or_circuit_t *circ, int is_rend_circ,
+ const uint8_t *token)
+{
+ digestmap_t **map_p, *map;
+ or_circuit_t *found_circ;
+
+ /* Find the right map, creating it as needed */
+ map_p = is_rend_circ ? &rend_cookie_map : &intro_digest_map;
+
+ if (!*map_p)
+ *map_p = digestmap_new();
+
+ map = *map_p;
+
+ /* If this circuit already has a token, we need to remove that. */
+ if (circ->rendinfo)
+ circuit_clear_rend_token(circ);
+
+ if (token == NULL) {
+ /* We were only trying to remove this token, not set a new one. */
+ return;
+ }
+
+ found_circ = digestmap_get(map, (const char *)token);
+ if (found_circ) {
+ tor_assert(found_circ != circ);
+ circuit_clear_rend_token(found_circ);
+ if (! found_circ->base_.marked_for_close) {
+ circuit_mark_for_close(TO_CIRCUIT(found_circ), END_CIRC_REASON_FINISHED);
+ if (is_rend_circ) {
+ log_fn(LOG_PROTOCOL_WARN, LD_REND,
+ "Duplicate rendezvous cookie (%s...) used on two circuits",
+ hex_str((const char*)token, 4)); /* only log first 4 chars */
+ }
+ }
+ }
+
+ /* Now set up the rendinfo */
+ circ->rendinfo = tor_malloc(sizeof(*circ->rendinfo));
+ memcpy(circ->rendinfo->rend_token, token, REND_TOKEN_LEN);
+ circ->rendinfo->is_rend_circ = is_rend_circ ? 1 : 0;
+
+ digestmap_set(map, (const char *)token, circ);
}
/** Return the circuit waiting for a rendezvous with the provided cookie.
* Return NULL if no such circuit is found.
*/
or_circuit_t *
-circuit_get_rendezvous(const char *cookie)
+circuit_get_rendezvous(const uint8_t *cookie)
{
return circuit_get_by_rend_token_and_purpose(
CIRCUIT_PURPOSE_REND_POINT_WAITING,
- cookie, REND_COOKIE_LEN);
+ 1, (const char*)cookie);
}
/** Return the circuit waiting for intro cells of the given digest.
* Return NULL if no such circuit is found.
*/
or_circuit_t *
-circuit_get_intro_point(const char *digest)
+circuit_get_intro_point(const uint8_t *digest)
{
return circuit_get_by_rend_token_and_purpose(
- CIRCUIT_PURPOSE_INTRO_POINT, digest,
- DIGEST_LEN);
+ CIRCUIT_PURPOSE_INTRO_POINT, 0,
+ (const char *)digest);
+}
+
+/** Set the rendezvous cookie of <b>circ</b> to <b>cookie</b>. If another
+ * circuit previously had that cookie, mark it. */
+void
+circuit_set_rendezvous_cookie(or_circuit_t *circ, const uint8_t *cookie)
+{
+ circuit_set_rend_token(circ, 1, cookie);
+}
+
+/** Set the intro point key digest of <b>circ</b> to <b>cookie</b>. If another
+ * circuit previously had that intro point digest, mark it. */
+void
+circuit_set_intro_point_digest(or_circuit_t *circ, const uint8_t *digest)
+{
+ circuit_set_rend_token(circ, 0, digest);
}
/** Return a circuit that is open, is CIRCUIT_PURPOSE_C_GENERAL,
diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h
index 54a7ef42f..2bbd20b83 100644
--- a/src/or/circuitlist.h
+++ b/src/or/circuitlist.h
@@ -46,8 +46,10 @@ origin_circuit_t *circuit_get_ready_rend_circ_by_rend_data(
const rend_data_t *rend_data);
origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
const char *digest, uint8_t purpose);
-or_circuit_t *circuit_get_rendezvous(const char *cookie);
-or_circuit_t *circuit_get_intro_point(const char *digest);
+or_circuit_t *circuit_get_rendezvous(const uint8_t *cookie);
+or_circuit_t *circuit_get_intro_point(const uint8_t *digest);
+void circuit_set_rendezvous_cookie(or_circuit_t *circ, const uint8_t *cookie);
+void circuit_set_intro_point_digest(or_circuit_t *circ, const uint8_t *digest);
origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose,
extend_info_t *info, int flags);
void circuit_mark_all_unused_circs(void);
diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c
index c093ecd26..e362b1b49 100644
--- a/src/or/circuitstats.c
+++ b/src/or/circuitstats.c
@@ -12,6 +12,7 @@
#include "config.h"
#include "confparse.h"
#include "control.h"
+#include "main.h"
#include "networkstatus.h"
#include "statefile.h"
@@ -1185,6 +1186,12 @@ circuit_build_times_needs_circuits_now(const circuit_build_times_t *cbt)
}
/**
+ * How long should we be unreachable before we think we need to check if
+ * our published IP address has changed.
+ */
+#define CIRCUIT_TIMEOUT_BEFORE_RECHECK_IP (60*3)
+
+/**
* Called to indicate that the network showed some signs of liveness,
* i.e. we received a cell.
*
@@ -1199,12 +1206,15 @@ circuit_build_times_network_is_live(circuit_build_times_t *cbt)
{
time_t now = approx_time();
if (cbt->liveness.nonlive_timeouts > 0) {
+ time_t time_since_live = now - cbt->liveness.network_last_live;
log_notice(LD_CIRC,
"Tor now sees network activity. Restoring circuit build "
"timeout recording. Network was down for %d seconds "
"during %d circuit attempts.",
- (int)(now - cbt->liveness.network_last_live),
+ (int)time_since_live,
cbt->liveness.nonlive_timeouts);
+ if (time_since_live > CIRCUIT_TIMEOUT_BEFORE_RECHECK_IP)
+ reschedule_descriptor_update_check();
}
cbt->liveness.network_last_live = now;
cbt->liveness.nonlive_timeouts = 0;
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 04ad2cc00..6572a918e 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1195,6 +1195,12 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
"your pluggable transport proxy stopped running.",
fmt_addrport(&TO_CONN(conn)->addr, TO_CONN(conn)->port),
transport_name, transport_name);
+
+ control_event_bootstrap_problem(
+ "Can't connect to bridge",
+ END_OR_CONN_REASON_PT_MISSING,
+ conn);
+
} else {
log_warn(LD_GENERAL, "Tried to connect to '%s' through a proxy, but "
"the proxy address could not be found.",
diff --git a/src/or/control.c b/src/or/control.c
index 23e2054f9..7f421a71d 100644..100755
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -2193,6 +2193,9 @@ static const getinfo_item_t getinfo_items[] = {
"v3 Networkstatus consensus as retrieved from a DirPort."),
ITEM("exit-policy/default", policies,
"The default value appended to the configured exit policy."),
+ ITEM("exit-policy/full", policies, "The entire exit policy of onion router"),
+ ITEM("exit-policy/ipv4", policies, "IPv4 parts of exit policy"),
+ ITEM("exit-policy/ipv6", policies, "IPv6 parts of exit policy"),
PREFIX("ip-to-country/", geoip, "Perform a GEOIP lookup"),
{ NULL, NULL, NULL, 0 }
};
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index b6c5dd41f..f5994e031 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2578,14 +2578,6 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
tor_assert(private_key);
tor_assert(cert);
- if (resolve_my_address(LOG_WARN, options, &addr, NULL, &hostname)<0) {
- log_warn(LD_NET, "Couldn't resolve my hostname");
- return NULL;
- }
- if (!hostname || !strchr(hostname, '.')) {
- tor_free(hostname);
- hostname = tor_dup_ip(addr);
- }
if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
log_err(LD_BUG, "Error computing signing key digest");
return NULL;
@@ -2594,6 +2586,14 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
log_err(LD_BUG, "Error computing identity key digest");
return NULL;
}
+ if (resolve_my_address(LOG_WARN, options, &addr, NULL, &hostname)<0) {
+ log_warn(LD_NET, "Couldn't resolve my hostname");
+ return NULL;
+ }
+ if (!hostname || !strchr(hostname, '.')) {
+ tor_free(hostname);
+ hostname = tor_dup_ip(addr);
+ }
if (options->VersioningAuthoritativeDir) {
client_versions = format_versions_list(options->RecommendedClientVersions);
diff --git a/src/or/main.c b/src/or/main.c
index feca35c44..86f343750 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1162,6 +1162,18 @@ get_signewnym_epoch(void)
return newnym_epoch;
}
+static time_t time_to_check_descriptor = 0;
+/**
+ * Update our schedule so that we'll check whether we need to update our
+ * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL
+ * seconds.
+ */
+void
+reschedule_descriptor_update_check(void)
+{
+ time_to_check_descriptor = 0;
+}
+
/** Perform regular maintenance tasks. This function gets run once per
* second by second_elapsed_callback().
*/
@@ -1171,7 +1183,6 @@ run_scheduled_events(time_t now)
static time_t last_rotated_x509_certificate = 0;
static time_t time_to_check_v3_certificate = 0;
static time_t time_to_check_listeners = 0;
- static time_t time_to_check_descriptor = 0;
static time_t time_to_download_networkstatus = 0;
static time_t time_to_shrink_memory = 0;
static time_t time_to_try_getting_descriptors = 0;
diff --git a/src/or/main.h b/src/or/main.h
index df302ffa7..a2f03d954 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -50,6 +50,7 @@ void directory_info_has_arrived(time_t now, int from_cache);
void ip_address_changed(int at_interface);
void dns_servers_relaunch_checks(void);
+void reschedule_descriptor_update_check(void);
long get_uptime(void);
unsigned get_signewnym_epoch(void);
diff --git a/src/or/or.h b/src/or/or.h
index 38ab1767e..e17b5816a 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -604,7 +604,8 @@ typedef enum {
#define END_OR_CONN_REASON_NO_ROUTE 6 /* no route to host/net */
#define END_OR_CONN_REASON_IO_ERROR 7 /* read/write error */
#define END_OR_CONN_REASON_RESOURCE_LIMIT 8 /* sockets, buffers, etc */
-#define END_OR_CONN_REASON_MISC 9
+#define END_OR_CONN_REASON_PT_MISSING 9 /* PT failed or not available */
+#define END_OR_CONN_REASON_MISC 10
/* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
* documentation of these. The values must match. */
@@ -3173,20 +3174,8 @@ typedef struct or_circuit_t {
* is not marked for close. */
struct or_circuit_t *rend_splice;
-#if REND_COOKIE_LEN >= DIGEST_LEN
-#define REND_TOKEN_LEN REND_COOKIE_LEN
-#else
-#define REND_TOKEN_LEN DIGEST_LEN
-#endif
+ struct or_circuit_rendinfo_s *rendinfo;
- /** A hash of location-hidden service's PK if purpose is INTRO_POINT, or a
- * rendezvous cookie if purpose is REND_POINT_WAITING. Filled with zeroes
- * otherwise.
- * ???? move to a subtype or adjunct structure? Wastes 20 bytes. -NM
- */
- char rend_token[REND_TOKEN_LEN];
-
- /* ???? move to a subtype or adjunct structure? Wastes 20 bytes -NM */
/** Stores KH for the handshake. */
char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */
@@ -3213,6 +3202,25 @@ typedef struct or_circuit_t {
uint32_t max_middle_cells;
} or_circuit_t;
+typedef struct or_circuit_rendinfo_s {
+
+#if REND_COOKIE_LEN != DIGEST_LEN
+#error "The REND_TOKEN_LEN macro assumes REND_COOKIE_LEN == DIGEST_LEN"
+#endif
+#define REND_TOKEN_LEN DIGEST_LEN
+
+ /** A hash of location-hidden service's PK if purpose is INTRO_POINT, or a
+ * rendezvous cookie if purpose is REND_POINT_WAITING. Filled with zeroes
+ * otherwise.
+ */
+ char rend_token[REND_TOKEN_LEN];
+
+ /** True if this is a rendezvous point circuit; false if this is an
+ * introduction point. */
+ unsigned is_rend_circ;
+
+} or_circuit_rendinfo_t;
+
/** Convert a circuit subtype to a circuit_t. */
#define TO_CIRCUIT(x) (&((x)->base_))
diff --git a/src/or/policies.c b/src/or/policies.c
index 42dc46b7f..8a91509a7 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -13,6 +13,7 @@
#include "dirserv.h"
#include "nodelist.h"
#include "policies.h"
+#include "router.h"
#include "routerparse.h"
#include "geoip.h"
#include "ht.h"
@@ -1692,6 +1693,28 @@ getinfo_helper_policies(control_connection_t *conn,
(void) errmsg;
if (!strcmp(question, "exit-policy/default")) {
*answer = tor_strdup(DEFAULT_EXIT_POLICY);
+ } else if (!strcmpstart(question, "exit-policy/")) {
+ const routerinfo_t *me = router_get_my_routerinfo();
+
+ int include_ipv4 = 0;
+ int include_ipv6 = 0;
+
+ if (!strcmp(question, "exit-policy/ipv4")) {
+ include_ipv4 = 1;
+ } else if (!strcmp(question, "exit-policy/ipv6")) {
+ include_ipv6 = 1;
+ } else if (!strcmp(question, "exit-policy/full")) {
+ include_ipv4 = include_ipv6 = 1;
+ } else {
+ return 0; /* No such key. */
+ }
+
+ if (!me) {
+ *errmsg = "router_get_my_routerinfo returned NULL";
+ return -1;
+ }
+
+ *answer = router_dump_exit_policy_to_string(me,include_ipv4,include_ipv6);
}
return 0;
}
diff --git a/src/or/reasons.c b/src/or/reasons.c
index 0674474e7..750e89bbe 100644
--- a/src/or/reasons.c
+++ b/src/or/reasons.c
@@ -231,6 +231,8 @@ orconn_end_reason_to_control_string(int r)
return "RESOURCELIMIT";
case END_OR_CONN_REASON_MISC:
return "MISC";
+ case END_OR_CONN_REASON_PT_MISSING:
+ return "PT_MISSING";
case 0:
return "";
default:
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index c68f6da59..110381680 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -94,7 +94,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
/* Close any other intro circuits with the same pk. */
c = NULL;
- while ((c = circuit_get_intro_point(pk_digest))) {
+ while ((c = circuit_get_intro_point((const uint8_t *)pk_digest))) {
log_info(LD_REND, "Replacing old circuit for service %s",
safe_str(serviceid));
circuit_mark_for_close(TO_CIRCUIT(c), END_CIRC_REASON_FINISHED);
@@ -111,7 +111,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
/* Now, set up this circuit. */
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_INTRO_POINT);
- memcpy(circ->rend_token, pk_digest, DIGEST_LEN);
+ circuit_set_intro_point_digest(circ, (uint8_t *)pk_digest);
log_info(LD_REND,
"Established introduction point on circuit %u for service %s",
@@ -165,7 +165,7 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
(char*)request, REND_SERVICE_ID_LEN);
/* The first 20 bytes are all we look at: they have a hash of Bob's PK. */
- intro_circ = circuit_get_intro_point((char*)request);
+ intro_circ = circuit_get_intro_point((const uint8_t*)request);
if (!intro_circ) {
log_info(LD_REND,
"No intro circ found for INTRODUCE1 cell (%s) from circuit %u; "
@@ -236,7 +236,7 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
goto err;
}
- if (circuit_get_rendezvous((char*)request)) {
+ if (circuit_get_rendezvous(request)) {
log_warn(LD_PROTOCOL,
"Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS.");
goto err;
@@ -252,7 +252,7 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
}
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_REND_POINT_WAITING);
- memcpy(circ->rend_token, request, REND_COOKIE_LEN);
+ circuit_set_rendezvous_cookie(circ, request);
base16_encode(hexid,9,(char*)request,4);
@@ -300,7 +300,7 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
"Got request for rendezvous from circuit %u to cookie %s.",
(unsigned)circ->p_circ_id, hexid);
- rend_circ = circuit_get_rendezvous((char*)request);
+ rend_circ = circuit_get_rendezvous(request);
if (!rend_circ) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Rejecting RENDEZVOUS1 cell with unrecognized rendezvous cookie %s.",
@@ -328,7 +328,7 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_REND_ESTABLISHED);
circuit_change_purpose(TO_CIRCUIT(rend_circ),
CIRCUIT_PURPOSE_REND_ESTABLISHED);
- memset(circ->rend_token, 0, REND_COOKIE_LEN);
+ circuit_set_rendezvous_cookie(circ, NULL);
rend_circ->rend_splice = circ;
circ->rend_splice = rend_circ;
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 500efaf20..abd78da73 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -82,7 +82,7 @@ typedef struct rend_service_port_config_t {
#define MAX_INTRO_CIRCS_PER_PERIOD 10
/** How many times will a hidden service operator attempt to connect to
* a requested rendezvous point before giving up? */
-#define MAX_REND_FAILURES 30
+#define MAX_REND_FAILURES 8
/** How many seconds should we spend trying to connect to a requested
* rendezvous point before giving up? */
#define MAX_REND_TIMEOUT 30
diff --git a/src/or/router.c b/src/or/router.c
index 1f5df4b89..389120be0 100644..100755
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -2398,20 +2398,13 @@ router_dump_router_to_string(routerinfo_t *router,
if (!router->exit_policy || !smartlist_len(router->exit_policy)) {
smartlist_add(chunks, tor_strdup("reject *:*\n"));
} else if (router->exit_policy) {
- int i;
- for (i = 0; i < smartlist_len(router->exit_policy); ++i) {
- char pbuf[POLICY_BUF_LEN];
- addr_policy_t *tmpe = smartlist_get(router->exit_policy, i);
- int result;
- if (tor_addr_family(&tmpe->addr) == AF_INET6)
- continue; /* Don't include IPv6 parts of address policy */
- result = policy_write_item(pbuf, POLICY_BUF_LEN, tmpe, 1);
- if (result < 0) {
- log_warn(LD_BUG,"descriptor policy_write_item ran out of room!");
- goto err;
- }
- smartlist_add_asprintf(chunks, "%s\n", pbuf);
- }
+ char *exit_policy = router_dump_exit_policy_to_string(router,1,0);
+
+ if (!exit_policy)
+ goto err;
+
+ smartlist_add_asprintf(chunks, "%s\n", exit_policy);
+ tor_free(exit_policy);
}
if (router->ipv6_exit_policy) {
@@ -2479,6 +2472,56 @@ router_dump_router_to_string(routerinfo_t *router,
return output;
}
+/**
+ * OR only: Given <b>router</b>, produce a string with its exit policy.
+ * If <b>include_ipv4</b> is true, include IPv4 entries.
+ * If <b>include_ipv6</b> is true, include IPv6 entries.
+ */
+char *
+router_dump_exit_policy_to_string(const routerinfo_t *router,
+ int include_ipv4,
+ int include_ipv6)
+{
+ smartlist_t *exit_policy_strings;
+ char *policy_string = NULL;
+
+ if ((!router->exit_policy) || (router->policy_is_reject_star)) {
+ return tor_strdup("reject *:*");
+ }
+
+ exit_policy_strings = smartlist_new();
+
+ SMARTLIST_FOREACH_BEGIN(router->exit_policy, addr_policy_t *, tmpe) {
+ char *pbuf;
+ int bytes_written_to_pbuf;
+ if ((tor_addr_family(&tmpe->addr) == AF_INET6) && (!include_ipv6)) {
+ continue; /* Don't include IPv6 parts of address policy */
+ }
+ if ((tor_addr_family(&tmpe->addr) == AF_INET) && (!include_ipv4)) {
+ continue; /* Don't include IPv4 parts of address policy */
+ }
+
+ pbuf = tor_malloc(POLICY_BUF_LEN);
+ bytes_written_to_pbuf = policy_write_item(pbuf,POLICY_BUF_LEN, tmpe, 1);
+
+ if (bytes_written_to_pbuf < 0) {
+ log_warn(LD_BUG, "router_dump_exit_policy_to_string ran out of room!");
+ tor_free(pbuf);
+ goto done;
+ }
+
+ smartlist_add(exit_policy_strings,pbuf);
+ } SMARTLIST_FOREACH_END(tmpe);
+
+ policy_string = smartlist_join_strings(exit_policy_strings, "\n", 0, NULL);
+
+ done:
+ SMARTLIST_FOREACH(exit_policy_strings, char *, str, tor_free(str));
+ smartlist_free(exit_policy_strings);
+
+ return policy_string;
+}
+
/** Copy the primary (IPv4) OR port (IP address and TCP port) for
* <b>router</b> into *<b>ap_out</b>. */
void
diff --git a/src/or/router.h b/src/or/router.h
index bf6cdbea3..28e1ed6e6 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -94,6 +94,9 @@ int router_pick_published_address(const or_options_t *options, uint32_t *addr);
int router_rebuild_descriptor(int force);
char *router_dump_router_to_string(routerinfo_t *router,
crypto_pk_t *ident_key);
+char *router_dump_exit_policy_to_string(const routerinfo_t *router,
+ int include_ipv4,
+ int include_ipv6);
void router_get_prim_orport(const routerinfo_t *router,
tor_addr_port_t *addr_port_out);
void router_get_pref_orport(const routerinfo_t *router,
diff --git a/src/test/include.am b/src/test/include.am
index c59ebb2ad..34bbe6b5e 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -43,6 +43,7 @@ src_test_test_SOURCES = \
src/test/test_config.c \
src/test/test_hs.c \
src/test/test_nodelist.c \
+ src/test/test_policy.c \
src/ext/tinytest.c
src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
diff --git a/src/test/test.c b/src/test/test.c
index 0e0fc6a4f..e82f323a9 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -598,343 +598,6 @@ test_circuit_timeout(void)
return;
}
-/* Helper: assert that short_policy parses and writes back out as itself,
- or as <b>expected</b> if that's provided. */
-static void
-test_short_policy_parse(const char *input,
- const char *expected)
-{
- short_policy_t *short_policy = NULL;
- char *out = NULL;
-
- if (expected == NULL)
- expected = input;
-
- short_policy = parse_short_policy(input);
- tt_assert(short_policy);
- out = write_short_policy(short_policy);
- tt_str_op(out, ==, expected);
-
- done:
- tor_free(out);
- short_policy_free(short_policy);
-}
-
-/** Helper: Parse the exit policy string in <b>policy_str</b>, and make sure
- * that policies_summarize() produces the string <b>expected_summary</b> from
- * it. */
-static void
-test_policy_summary_helper(const char *policy_str,
- const char *expected_summary)
-{
- config_line_t line;
- smartlist_t *policy = smartlist_new();
- char *summary = NULL;
- char *summary_after = NULL;
- int r;
- short_policy_t *short_policy = NULL;
-
- line.key = (char*)"foo";
- line.value = (char *)policy_str;
- line.next = NULL;
-
- r = policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1);
- test_eq(r, 0);
- summary = policy_summarize(policy, AF_INET);
-
- test_assert(summary != NULL);
- test_streq(summary, expected_summary);
-
- short_policy = parse_short_policy(summary);
- tt_assert(short_policy);
- summary_after = write_short_policy(short_policy);
- test_streq(summary, summary_after);
-
- done:
- tor_free(summary_after);
- tor_free(summary);
- if (policy)
- addr_policy_list_free(policy);
- short_policy_free(short_policy);
-}
-
-/** Run unit tests for generating summary lines of exit policies */
-static void
-test_policies(void)
-{
- int i;
- smartlist_t *policy = NULL, *policy2 = NULL, *policy3 = NULL,
- *policy4 = NULL, *policy5 = NULL, *policy6 = NULL,
- *policy7 = NULL;
- addr_policy_t *p;
- tor_addr_t tar;
- config_line_t line;
- smartlist_t *sm = NULL;
- char *policy_str = NULL;
- short_policy_t *short_parsed = NULL;
-
- policy = smartlist_new();
-
- p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
- test_assert(p != NULL);
- test_eq(ADDR_POLICY_REJECT, p->policy_type);
- tor_addr_from_ipv4h(&tar, 0xc0a80000u);
- test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
- test_eq(16, p->maskbits);
- test_eq(1, p->prt_min);
- test_eq(65535, p->prt_max);
-
- smartlist_add(policy, p);
-
- tor_addr_from_ipv4h(&tar, 0x01020304u);
- test_assert(ADDR_POLICY_ACCEPTED ==
- compare_tor_addr_to_addr_policy(&tar, 2, policy));
- tor_addr_make_unspec(&tar);
- test_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
- compare_tor_addr_to_addr_policy(&tar, 2, policy));
- tor_addr_from_ipv4h(&tar, 0xc0a80102);
- test_assert(ADDR_POLICY_REJECTED ==
- compare_tor_addr_to_addr_policy(&tar, 2, policy));
-
- test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, 0, 1));
- test_assert(policy2);
-
- policy3 = smartlist_new();
- p = router_parse_addr_policy_item_from_string("reject *:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy3, p);
- p = router_parse_addr_policy_item_from_string("accept *:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy3, p);
-
- policy4 = smartlist_new();
- p = router_parse_addr_policy_item_from_string("accept *:443",-1);
- test_assert(p != NULL);
- smartlist_add(policy4, p);
- p = router_parse_addr_policy_item_from_string("accept *:443",-1);
- test_assert(p != NULL);
- smartlist_add(policy4, p);
-
- policy5 = smartlist_new();
- p = router_parse_addr_policy_item_from_string("reject 0.0.0.0/8:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject 169.254.0.0/16:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject 127.0.0.0/8:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject 10.0.0.0/8:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject 172.16.0.0/12:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject 80.190.250.90:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject *:1-65534",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("reject *:65535",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
- p = router_parse_addr_policy_item_from_string("accept *:1-65535",-1);
- test_assert(p != NULL);
- smartlist_add(policy5, p);
-
- policy6 = smartlist_new();
- p = router_parse_addr_policy_item_from_string("accept 43.3.0.0/9:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy6, p);
-
- policy7 = smartlist_new();
- p = router_parse_addr_policy_item_from_string("accept 0.0.0.0/8:*",-1);
- test_assert(p != NULL);
- smartlist_add(policy7, p);
-
- test_assert(!exit_policy_is_general_exit(policy));
- test_assert(exit_policy_is_general_exit(policy2));
- test_assert(!exit_policy_is_general_exit(NULL));
- test_assert(!exit_policy_is_general_exit(policy3));
- test_assert(!exit_policy_is_general_exit(policy4));
- test_assert(!exit_policy_is_general_exit(policy5));
- test_assert(!exit_policy_is_general_exit(policy6));
- test_assert(!exit_policy_is_general_exit(policy7));
-
- test_assert(cmp_addr_policies(policy, policy2));
- test_assert(cmp_addr_policies(policy, NULL));
- test_assert(!cmp_addr_policies(policy2, policy2));
- test_assert(!cmp_addr_policies(NULL, NULL));
-
- test_assert(!policy_is_reject_star(policy2, AF_INET));
- test_assert(policy_is_reject_star(policy, AF_INET));
- test_assert(policy_is_reject_star(NULL, AF_INET));
-
- addr_policy_list_free(policy);
- policy = NULL;
-
- /* make sure compacting logic works. */
- policy = NULL;
- line.key = (char*)"foo";
- line.value = (char*)"accept *:80,reject private:*,reject *:*";
- line.next = NULL;
- test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1));
- test_assert(policy);
- //test_streq(policy->string, "accept *:80");
- //test_streq(policy->next->string, "reject *:*");
- test_eq(smartlist_len(policy), 4);
-
- /* test policy summaries */
- /* check if we properly ignore private IP addresses */
- test_policy_summary_helper("reject 192.168.0.0/16:*,"
- "reject 0.0.0.0/8:*,"
- "reject 10.0.0.0/8:*,"
- "accept *:10-30,"
- "accept *:90,"
- "reject *:*",
- "accept 10-30,90");
- /* check all accept policies, and proper counting of rejects */
- test_policy_summary_helper("reject 11.0.0.0/9:80,"
- "reject 12.0.0.0/9:80,"
- "reject 13.0.0.0/9:80,"
- "reject 14.0.0.0/9:80,"
- "accept *:*", "accept 1-65535");
- test_policy_summary_helper("reject 11.0.0.0/9:80,"
- "reject 12.0.0.0/9:80,"
- "reject 13.0.0.0/9:80,"
- "reject 14.0.0.0/9:80,"
- "reject 15.0.0.0:81,"
- "accept *:*", "accept 1-65535");
- test_policy_summary_helper("reject 11.0.0.0/9:80,"
- "reject 12.0.0.0/9:80,"
- "reject 13.0.0.0/9:80,"
- "reject 14.0.0.0/9:80,"
- "reject 15.0.0.0:80,"
- "accept *:*",
- "reject 80");
- /* no exits */
- test_policy_summary_helper("accept 11.0.0.0/9:80,"
- "reject *:*",
- "reject 1-65535");
- /* port merging */
- test_policy_summary_helper("accept *:80,"
- "accept *:81,"
- "accept *:100-110,"
- "accept *:111,"
- "reject *:*",
- "accept 80-81,100-111");
- /* border ports */
- test_policy_summary_helper("accept *:1,"
- "accept *:3,"
- "accept *:65535,"
- "reject *:*",
- "accept 1,3,65535");
- /* holes */
- test_policy_summary_helper("accept *:1,"
- "accept *:3,"
- "accept *:5,"
- "accept *:7,"
- "reject *:*",
- "accept 1,3,5,7");
- test_policy_summary_helper("reject *:1,"
- "reject *:3,"
- "reject *:5,"
- "reject *:7,"
- "accept *:*",
- "reject 1,3,5,7");
-
- /* Short policies with unrecognized formats should get accepted. */
- test_short_policy_parse("accept fred,2,3-5", "accept 2,3-5");
- test_short_policy_parse("accept 2,fred,3", "accept 2,3");
- test_short_policy_parse("accept 2,fred,3,bob", "accept 2,3");
- test_short_policy_parse("accept 2,-3,500-600", "accept 2,500-600");
- /* Short policies with nil entries are accepted too. */
- test_short_policy_parse("accept 1,,3", "accept 1,3");
- test_short_policy_parse("accept 100-200,,", "accept 100-200");
- test_short_policy_parse("reject ,1-10,,,,30-40", "reject 1-10,30-40");
-
- /* Try parsing various broken short policies */
-#define TT_BAD_SHORT_POLICY(s) \
- do { \
- tt_ptr_op(NULL, ==, (short_parsed = parse_short_policy((s)))); \
- } while (0)
- TT_BAD_SHORT_POLICY("accept 200-199");
- TT_BAD_SHORT_POLICY("");
- TT_BAD_SHORT_POLICY("rejekt 1,2,3");
- TT_BAD_SHORT_POLICY("reject ");
- TT_BAD_SHORT_POLICY("reject");
- TT_BAD_SHORT_POLICY("rej");
- TT_BAD_SHORT_POLICY("accept 2,3,100000");
- TT_BAD_SHORT_POLICY("accept 2,3x,4");
- TT_BAD_SHORT_POLICY("accept 2,3x,4");
- TT_BAD_SHORT_POLICY("accept 2-");
- TT_BAD_SHORT_POLICY("accept 2-x");
- TT_BAD_SHORT_POLICY("accept 1-,3");
- TT_BAD_SHORT_POLICY("accept 1-,3");
-
- /* Test a too-long policy. */
- {
- int i;
- char *policy = NULL;
- smartlist_t *chunks = smartlist_new();
- smartlist_add(chunks, tor_strdup("accept "));
- for (i=1; i<10000; ++i)
- smartlist_add_asprintf(chunks, "%d,", i);
- smartlist_add(chunks, tor_strdup("20000"));
- policy = smartlist_join_strings(chunks, "", 0, NULL);
- SMARTLIST_FOREACH(chunks, char *, ch, tor_free(ch));
- smartlist_free(chunks);
- short_parsed = parse_short_policy(policy);/* shouldn't be accepted */
- tor_free(policy);
- tt_ptr_op(NULL, ==, short_parsed);
- }
-
- /* truncation ports */
- sm = smartlist_new();
- for (i=1; i<2000; i+=2) {
- char buf[POLICY_BUF_LEN];
- tor_snprintf(buf, sizeof(buf), "reject *:%d", i);
- smartlist_add(sm, tor_strdup(buf));
- }
- smartlist_add(sm, tor_strdup("accept *:*"));
- policy_str = smartlist_join_strings(sm, ",", 0, NULL);
- test_policy_summary_helper( policy_str,
- "accept 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,"
- "46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,"
- "92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,"
- "130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,"
- "166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,"
- "202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,"
- "238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,"
- "274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,"
- "310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,"
- "346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,"
- "382,384,386,388,390,392,394,396,398,400,402,404,406,408,410,412,414,416,"
- "418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,"
- "454,456,458,460,462,464,466,468,470,472,474,476,478,480,482,484,486,488,"
- "490,492,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522");
-
- done:
- addr_policy_list_free(policy);
- addr_policy_list_free(policy2);
- addr_policy_list_free(policy3);
- addr_policy_list_free(policy4);
- addr_policy_list_free(policy5);
- addr_policy_list_free(policy6);
- addr_policy_list_free(policy7);
- tor_free(policy_str);
- if (sm) {
- SMARTLIST_FOREACH(sm, char *, s, tor_free(s));
- smartlist_free(sm);
- }
- short_policy_free(short_parsed);
-}
-
/** Test encoding and parsing of rendezvous service descriptors. */
static void
test_rend_fns(void)
@@ -1603,7 +1266,6 @@ static struct testcase_t test_array[] = {
{ "ntor_handshake", test_ntor_handshake, 0, NULL, NULL },
#endif
ENT(circuit_timeout),
- ENT(policies),
ENT(rend_fns),
ENT(geoip),
FORK(geoip_with_pt),
@@ -1633,11 +1295,11 @@ extern struct testcase_t socks_tests[];
extern struct testcase_t extorport_tests[];
extern struct testcase_t controller_event_tests[];
extern struct testcase_t logging_tests[];
-extern struct testcase_t backtrace_tests[];
extern struct testcase_t hs_tests[];
extern struct testcase_t nodelist_tests[];
extern struct testcase_t routerkeys_tests[];
extern struct testcase_t oom_tests[];
+extern struct testcase_t policy_tests[];
static struct testgroup_t testgroups[] = {
{ "", test_array },
@@ -1666,6 +1328,7 @@ static struct testgroup_t testgroups[] = {
{ "nodelist/", nodelist_tests },
{ "routerkeys/", routerkeys_tests },
{ "oom/", oom_tests },
+ { "policy/" , policy_tests },
END_OF_GROUPS
};
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index eb25e0b48..cee2dcf2a 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -73,7 +73,7 @@ test_addr_basic(void)
}
done:
- ;
+ tor_free(cp);
}
#define test_op_ip6_(a,op,b,e1,e2) \
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index 54aa51d3c..54c0c03ca 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -161,8 +161,98 @@ test_clist_maps(void *arg)
UNMOCK(circuitmux_detach_circuit);
}
+static void
+test_rend_token_maps(void *arg)
+{
+ or_circuit_t *c1, *c2, *c3, *c4;
+ const uint8_t tok1[REND_TOKEN_LEN] = "The cat can't tell y";
+ const uint8_t tok2[REND_TOKEN_LEN] = "ou its name, and it ";
+ const uint8_t tok3[REND_TOKEN_LEN] = "doesn't really care.";
+ /* -- Adapted from a quote by Fredrik Lundh. */
+
+ (void)arg;
+ (void)tok1; //xxxx
+ c1 = or_circuit_new(0, NULL);
+ c2 = or_circuit_new(0, NULL);
+ c3 = or_circuit_new(0, NULL);
+ c4 = or_circuit_new(0, NULL);
+
+ tt_int_op(strlen((char*)tok1), ==, REND_TOKEN_LEN);
+
+ /* No maps; nothing there. */
+ tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok1));
+ tt_ptr_op(NULL, ==, circuit_get_intro_point(tok1));
+
+ circuit_set_rendezvous_cookie(c1, tok1);
+ circuit_set_intro_point_digest(c2, tok2);
+
+ tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok3));
+ tt_ptr_op(NULL, ==, circuit_get_intro_point(tok3));
+ tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok2));
+ tt_ptr_op(NULL, ==, circuit_get_intro_point(tok1));
+
+ /* Without purpose set, we don't get the circuits */
+ tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok1));
+ tt_ptr_op(NULL, ==, circuit_get_intro_point(tok2));
+
+ c1->base_.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
+ c2->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
+
+ /* Okay, make sure they show up now. */
+ tt_ptr_op(c1, ==, circuit_get_rendezvous(tok1));
+ tt_ptr_op(c2, ==, circuit_get_intro_point(tok2));
+
+ /* Two items at the same place with the same token. */
+ c3->base_.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
+ circuit_set_rendezvous_cookie(c3, tok2);
+ tt_ptr_op(c2, ==, circuit_get_intro_point(tok2));
+ tt_ptr_op(c3, ==, circuit_get_rendezvous(tok2));
+
+ /* Marking a circuit makes it not get returned any more */
+ circuit_mark_for_close(TO_CIRCUIT(c1), END_CIRC_REASON_FINISHED);
+ tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok1));
+ circuit_free(TO_CIRCUIT(c1));
+ c1 = NULL;
+
+ /* Freeing a circuit makes it not get returned any more. */
+ circuit_free(TO_CIRCUIT(c2));
+ c2 = NULL;
+ tt_ptr_op(NULL, ==, circuit_get_intro_point(tok2));
+
+ /* c3 -- are you still there? */
+ tt_ptr_op(c3, ==, circuit_get_rendezvous(tok2));
+ /* Change its cookie. This never happens in Tor per se, but hey. */
+ c3->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
+ circuit_set_intro_point_digest(c3, tok3);
+
+ tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok2));
+ tt_ptr_op(c3, ==, circuit_get_intro_point(tok3));
+
+ /* Now replace c3 with c4. */
+ c4->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
+ circuit_set_intro_point_digest(c4, tok3);
+
+ tt_ptr_op(c4, ==, circuit_get_intro_point(tok3));
+
+ tt_ptr_op(c3->rendinfo, ==, NULL);
+ tt_ptr_op(c4->rendinfo, !=, NULL);
+ test_mem_op(c4->rendinfo, ==, tok3, REND_TOKEN_LEN);
+
+ /* Now clear c4's cookie. */
+ circuit_set_intro_point_digest(c4, NULL);
+ tt_ptr_op(c4->rendinfo, ==, NULL);
+ tt_ptr_op(NULL, ==, circuit_get_intro_point(tok3));
+
+ done:
+ circuit_free(TO_CIRCUIT(c1));
+ circuit_free(TO_CIRCUIT(c2));
+ circuit_free(TO_CIRCUIT(c3));
+ circuit_free(TO_CIRCUIT(c4));
+}
+
struct testcase_t circuitlist_tests[] = {
{ "maps", test_clist_maps, TT_FORK, NULL, NULL },
+ { "rend_token_maps", test_rend_token_maps, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
new file mode 100644
index 000000000..d2ba1612d
--- /dev/null
+++ b/src/test/test_policy.c
@@ -0,0 +1,432 @@
+/* Copyright (c) 2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "or.h"
+#include "router.h"
+#include "routerparse.h"
+#include "policies.h"
+#include "test.h"
+
+/* Helper: assert that short_policy parses and writes back out as itself,
+ or as <b>expected</b> if that's provided. */
+static void
+test_short_policy_parse(const char *input,
+ const char *expected)
+{
+ short_policy_t *short_policy = NULL;
+ char *out = NULL;
+
+ if (expected == NULL)
+ expected = input;
+
+ short_policy = parse_short_policy(input);
+ tt_assert(short_policy);
+ out = write_short_policy(short_policy);
+ tt_str_op(out, ==, expected);
+
+ done:
+ tor_free(out);
+ short_policy_free(short_policy);
+}
+
+/** Helper: Parse the exit policy string in <b>policy_str</b>, and make sure
+ * that policies_summarize() produces the string <b>expected_summary</b> from
+ * it. */
+static void
+test_policy_summary_helper(const char *policy_str,
+ const char *expected_summary)
+{
+ config_line_t line;
+ smartlist_t *policy = smartlist_new();
+ char *summary = NULL;
+ char *summary_after = NULL;
+ int r;
+ short_policy_t *short_policy = NULL;
+
+ line.key = (char*)"foo";
+ line.value = (char *)policy_str;
+ line.next = NULL;
+
+ r = policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1);
+ test_eq(r, 0);
+ summary = policy_summarize(policy, AF_INET);
+
+ test_assert(summary != NULL);
+ test_streq(summary, expected_summary);
+
+ short_policy = parse_short_policy(summary);
+ tt_assert(short_policy);
+ summary_after = write_short_policy(short_policy);
+ test_streq(summary, summary_after);
+
+ done:
+ tor_free(summary_after);
+ tor_free(summary);
+ if (policy)
+ addr_policy_list_free(policy);
+ short_policy_free(short_policy);
+}
+
+/** Run unit tests for generating summary lines of exit policies */
+static void
+test_policies_general(void *arg)
+{
+ int i;
+ smartlist_t *policy = NULL, *policy2 = NULL, *policy3 = NULL,
+ *policy4 = NULL, *policy5 = NULL, *policy6 = NULL,
+ *policy7 = NULL;
+ addr_policy_t *p;
+ tor_addr_t tar;
+ config_line_t line;
+ smartlist_t *sm = NULL;
+ char *policy_str = NULL;
+ short_policy_t *short_parsed = NULL;
+ (void)arg;
+
+ policy = smartlist_new();
+
+ p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
+ test_assert(p != NULL);
+ test_eq(ADDR_POLICY_REJECT, p->policy_type);
+ tor_addr_from_ipv4h(&tar, 0xc0a80000u);
+ test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
+ test_eq(16, p->maskbits);
+ test_eq(1, p->prt_min);
+ test_eq(65535, p->prt_max);
+
+ smartlist_add(policy, p);
+
+ tor_addr_from_ipv4h(&tar, 0x01020304u);
+ test_assert(ADDR_POLICY_ACCEPTED ==
+ compare_tor_addr_to_addr_policy(&tar, 2, policy));
+ tor_addr_make_unspec(&tar);
+ test_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
+ compare_tor_addr_to_addr_policy(&tar, 2, policy));
+ tor_addr_from_ipv4h(&tar, 0xc0a80102);
+ test_assert(ADDR_POLICY_REJECTED ==
+ compare_tor_addr_to_addr_policy(&tar, 2, policy));
+
+ test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, 0, 1));
+ test_assert(policy2);
+
+ policy3 = smartlist_new();
+ p = router_parse_addr_policy_item_from_string("reject *:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy3, p);
+ p = router_parse_addr_policy_item_from_string("accept *:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy3, p);
+
+ policy4 = smartlist_new();
+ p = router_parse_addr_policy_item_from_string("accept *:443",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy4, p);
+ p = router_parse_addr_policy_item_from_string("accept *:443",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy4, p);
+
+ policy5 = smartlist_new();
+ p = router_parse_addr_policy_item_from_string("reject 0.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 169.254.0.0/16:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 127.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 10.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 172.16.0.0/12:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject 80.190.250.90:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject *:1-65534",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("reject *:65535",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+ p = router_parse_addr_policy_item_from_string("accept *:1-65535",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy5, p);
+
+ policy6 = smartlist_new();
+ p = router_parse_addr_policy_item_from_string("accept 43.3.0.0/9:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy6, p);
+
+ policy7 = smartlist_new();
+ p = router_parse_addr_policy_item_from_string("accept 0.0.0.0/8:*",-1);
+ test_assert(p != NULL);
+ smartlist_add(policy7, p);
+
+ test_assert(!exit_policy_is_general_exit(policy));
+ test_assert(exit_policy_is_general_exit(policy2));
+ test_assert(!exit_policy_is_general_exit(NULL));
+ test_assert(!exit_policy_is_general_exit(policy3));
+ test_assert(!exit_policy_is_general_exit(policy4));
+ test_assert(!exit_policy_is_general_exit(policy5));
+ test_assert(!exit_policy_is_general_exit(policy6));
+ test_assert(!exit_policy_is_general_exit(policy7));
+
+ test_assert(cmp_addr_policies(policy, policy2));
+ test_assert(cmp_addr_policies(policy, NULL));
+ test_assert(!cmp_addr_policies(policy2, policy2));
+ test_assert(!cmp_addr_policies(NULL, NULL));
+
+ test_assert(!policy_is_reject_star(policy2, AF_INET));
+ test_assert(policy_is_reject_star(policy, AF_INET));
+ test_assert(policy_is_reject_star(NULL, AF_INET));
+
+ addr_policy_list_free(policy);
+ policy = NULL;
+
+ /* make sure compacting logic works. */
+ policy = NULL;
+ line.key = (char*)"foo";
+ line.value = (char*)"accept *:80,reject private:*,reject *:*";
+ line.next = NULL;
+ test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1));
+ test_assert(policy);
+ //test_streq(policy->string, "accept *:80");
+ //test_streq(policy->next->string, "reject *:*");
+ test_eq(smartlist_len(policy), 4);
+
+ /* test policy summaries */
+ /* check if we properly ignore private IP addresses */
+ test_policy_summary_helper("reject 192.168.0.0/16:*,"
+ "reject 0.0.0.0/8:*,"
+ "reject 10.0.0.0/8:*,"
+ "accept *:10-30,"
+ "accept *:90,"
+ "reject *:*",
+ "accept 10-30,90");
+ /* check all accept policies, and proper counting of rejects */
+ test_policy_summary_helper("reject 11.0.0.0/9:80,"
+ "reject 12.0.0.0/9:80,"
+ "reject 13.0.0.0/9:80,"
+ "reject 14.0.0.0/9:80,"
+ "accept *:*", "accept 1-65535");
+ test_policy_summary_helper("reject 11.0.0.0/9:80,"
+ "reject 12.0.0.0/9:80,"
+ "reject 13.0.0.0/9:80,"
+ "reject 14.0.0.0/9:80,"
+ "reject 15.0.0.0:81,"
+ "accept *:*", "accept 1-65535");
+ test_policy_summary_helper("reject 11.0.0.0/9:80,"
+ "reject 12.0.0.0/9:80,"
+ "reject 13.0.0.0/9:80,"
+ "reject 14.0.0.0/9:80,"
+ "reject 15.0.0.0:80,"
+ "accept *:*",
+ "reject 80");
+ /* no exits */
+ test_policy_summary_helper("accept 11.0.0.0/9:80,"
+ "reject *:*",
+ "reject 1-65535");
+ /* port merging */
+ test_policy_summary_helper("accept *:80,"
+ "accept *:81,"
+ "accept *:100-110,"
+ "accept *:111,"
+ "reject *:*",
+ "accept 80-81,100-111");
+ /* border ports */
+ test_policy_summary_helper("accept *:1,"
+ "accept *:3,"
+ "accept *:65535,"
+ "reject *:*",
+ "accept 1,3,65535");
+ /* holes */
+ test_policy_summary_helper("accept *:1,"
+ "accept *:3,"
+ "accept *:5,"
+ "accept *:7,"
+ "reject *:*",
+ "accept 1,3,5,7");
+ test_policy_summary_helper("reject *:1,"
+ "reject *:3,"
+ "reject *:5,"
+ "reject *:7,"
+ "accept *:*",
+ "reject 1,3,5,7");
+
+ /* Short policies with unrecognized formats should get accepted. */
+ test_short_policy_parse("accept fred,2,3-5", "accept 2,3-5");
+ test_short_policy_parse("accept 2,fred,3", "accept 2,3");
+ test_short_policy_parse("accept 2,fred,3,bob", "accept 2,3");
+ test_short_policy_parse("accept 2,-3,500-600", "accept 2,500-600");
+ /* Short policies with nil entries are accepted too. */
+ test_short_policy_parse("accept 1,,3", "accept 1,3");
+ test_short_policy_parse("accept 100-200,,", "accept 100-200");
+ test_short_policy_parse("reject ,1-10,,,,30-40", "reject 1-10,30-40");
+
+ /* Try parsing various broken short policies */
+#define TT_BAD_SHORT_POLICY(s) \
+ do { \
+ tt_ptr_op(NULL, ==, (short_parsed = parse_short_policy((s)))); \
+ } while (0)
+ TT_BAD_SHORT_POLICY("accept 200-199");
+ TT_BAD_SHORT_POLICY("");
+ TT_BAD_SHORT_POLICY("rejekt 1,2,3");
+ TT_BAD_SHORT_POLICY("reject ");
+ TT_BAD_SHORT_POLICY("reject");
+ TT_BAD_SHORT_POLICY("rej");
+ TT_BAD_SHORT_POLICY("accept 2,3,100000");
+ TT_BAD_SHORT_POLICY("accept 2,3x,4");
+ TT_BAD_SHORT_POLICY("accept 2,3x,4");
+ TT_BAD_SHORT_POLICY("accept 2-");
+ TT_BAD_SHORT_POLICY("accept 2-x");
+ TT_BAD_SHORT_POLICY("accept 1-,3");
+ TT_BAD_SHORT_POLICY("accept 1-,3");
+
+ /* Test a too-long policy. */
+ {
+ int i;
+ char *policy = NULL;
+ smartlist_t *chunks = smartlist_new();
+ smartlist_add(chunks, tor_strdup("accept "));
+ for (i=1; i<10000; ++i)
+ smartlist_add_asprintf(chunks, "%d,", i);
+ smartlist_add(chunks, tor_strdup("20000"));
+ policy = smartlist_join_strings(chunks, "", 0, NULL);
+ SMARTLIST_FOREACH(chunks, char *, ch, tor_free(ch));
+ smartlist_free(chunks);
+ short_parsed = parse_short_policy(policy);/* shouldn't be accepted */
+ tor_free(policy);
+ tt_ptr_op(NULL, ==, short_parsed);
+ }
+
+ /* truncation ports */
+ sm = smartlist_new();
+ for (i=1; i<2000; i+=2) {
+ char buf[POLICY_BUF_LEN];
+ tor_snprintf(buf, sizeof(buf), "reject *:%d", i);
+ smartlist_add(sm, tor_strdup(buf));
+ }
+ smartlist_add(sm, tor_strdup("accept *:*"));
+ policy_str = smartlist_join_strings(sm, ",", 0, NULL);
+ test_policy_summary_helper( policy_str,
+ "accept 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,"
+ "46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,"
+ "92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,"
+ "130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,"
+ "166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,"
+ "202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,"
+ "238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,"
+ "274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,"
+ "310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,"
+ "346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,"
+ "382,384,386,388,390,392,394,396,398,400,402,404,406,408,410,412,414,416,"
+ "418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,"
+ "454,456,458,460,462,464,466,468,470,472,474,476,478,480,482,484,486,488,"
+ "490,492,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522");
+
+ done:
+ addr_policy_list_free(policy);
+ addr_policy_list_free(policy2);
+ addr_policy_list_free(policy3);
+ addr_policy_list_free(policy4);
+ addr_policy_list_free(policy5);
+ addr_policy_list_free(policy6);
+ addr_policy_list_free(policy7);
+ tor_free(policy_str);
+ if (sm) {
+ SMARTLIST_FOREACH(sm, char *, s, tor_free(s));
+ smartlist_free(sm);
+ }
+ short_policy_free(short_parsed);
+}
+
+static void
+test_dump_exit_policy_to_string(void *arg)
+{
+ char *ep;
+ addr_policy_t *policy_entry;
+
+ routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t));
+
+ (void)arg;
+
+ ri->policy_is_reject_star = 1;
+ ri->exit_policy = NULL; // expecting "reject *:*"
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("reject *:*",ep);
+
+ tor_free(ep);
+
+ ri->exit_policy = smartlist_new();
+ ri->policy_is_reject_star = 0;
+
+ policy_entry = router_parse_addr_policy_item_from_string("accept *:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*",ep);
+
+ tor_free(ep);
+
+ policy_entry = router_parse_addr_policy_item_from_string("reject *:25",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25",ep);
+
+ tor_free(ep);
+
+ policy_entry =
+ router_parse_addr_policy_item_from_string("reject 8.8.8.8:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*",ep);
+
+ policy_entry =
+ router_parse_addr_policy_item_from_string("reject6 [FC00::]/7:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
+ "reject6 [fc00::]/7:*",ep);
+
+ policy_entry =
+ router_parse_addr_policy_item_from_string("accept6 [c000::]/3:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
+ "reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",ep);
+
+ done:
+
+ SMARTLIST_FOREACH(ri->exit_policy, addr_policy_t *,
+ entry, addr_policy_free(entry));
+ tor_free(ri);
+ tor_free(ep);
+}
+
+struct testcase_t policy_tests[] = {
+ { "router_dump_exit_policy_to_string", test_dump_exit_policy_to_string, 0,
+ NULL, NULL },
+ { "general", test_policies_general, 0, NULL, NULL },
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_util.c b/src/test/test_util.c
index a471b8eb1..08efd453c 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1189,19 +1189,19 @@ test_util_strmisc(void)
}
/* Test str-foo functions */
- cp = tor_strdup("abcdef");
- test_assert(tor_strisnonupper(cp));
- cp[3] = 'D';
- test_assert(!tor_strisnonupper(cp));
- tor_strupper(cp);
- test_streq(cp, "ABCDEF");
- tor_strlower(cp);
- test_streq(cp, "abcdef");
- test_assert(tor_strisnonupper(cp));
- test_assert(tor_strisprint(cp));
- cp[3] = 3;
- test_assert(!tor_strisprint(cp));
- tor_free(cp);
+ cp_tmp = tor_strdup("abcdef");
+ test_assert(tor_strisnonupper(cp_tmp));
+ cp_tmp[3] = 'D';
+ test_assert(!tor_strisnonupper(cp_tmp));
+ tor_strupper(cp_tmp);
+ test_streq(cp_tmp, "ABCDEF");
+ tor_strlower(cp_tmp);
+ test_streq(cp_tmp, "abcdef");
+ test_assert(tor_strisnonupper(cp_tmp));
+ test_assert(tor_strisprint(cp_tmp));
+ cp_tmp[3] = 3;
+ test_assert(!tor_strisprint(cp_tmp));
+ tor_free(cp_tmp);
/* Test memmem and memstr */
{
@@ -1212,6 +1212,10 @@ test_util_strmisc(void)
test_assert(!tor_memmem(haystack, 4, "cde", 3));
haystack = "ababcad";
test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
+ test_eq_ptr(tor_memmem(haystack, 7, "ad", 2), haystack + 5);
+ test_eq_ptr(tor_memmem(haystack, 7, "cad", 3), haystack + 4);
+ test_assert(!tor_memmem(haystack, 7, "dadad", 5));
+ test_assert(!tor_memmem(haystack, 7, "abcdefghij", 10));
/* memstr */
test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
test_eq_ptr(tor_memstr(haystack, 7, "cad"), haystack + 4);
@@ -2321,6 +2325,8 @@ test_util_listdir(void *ptr)
done:
tor_free(fname1);
tor_free(fname2);
+ tor_free(fname3);
+ tor_free(dir1);
tor_free(dirname);
if (dir_contents) {
SMARTLIST_FOREACH(dir_contents, char *, cp, tor_free(cp));
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index 2f95cf7c5..d0c30b8b0 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -547,6 +547,9 @@ main(int argc, char **argv)
if (signing_key)
EVP_PKEY_free(signing_key);
tor_free(address);
+ tor_free(identity_key_file);
+ tor_free(signing_key_file);
+ tor_free(certificate_file);
crypto_global_cleanup();
return r;