diff options
Diffstat (limited to 'src')
40 files changed, 767 insertions, 557 deletions
diff --git a/src/common/compat.h b/src/common/compat.h index 8f35dfd110..c5df4dc20c 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -42,6 +42,15 @@ #include <netinet6/in6.h> #endif +#if defined(__has_feature) +# if __has_feature(address_sanitizer) +/* Some of the fancy glibc strcmp() macros include references to memory that + * clang rejects because it is off the end of a less-than-3. Clang hates this, + * even though those references never actually happen. */ +# undef strcmp +# endif +#endif + #include <stdio.h> #include <errno.h> diff --git a/src/common/container.c b/src/common/container.c index 2e42c9ee07..1de8e7ded4 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -840,9 +840,17 @@ smartlist_sort_pointers(smartlist_t *sl) * * For a 1-indexed array, we would use LEFT_CHILD[x] = 2*x and RIGHT_CHILD[x] * = 2*x + 1. But this is C, so we have to adjust a little. */ -//#define LEFT_CHILD(i) ( ((i)+1)*2 - 1) -//#define RIGHT_CHILD(i) ( ((i)+1)*2 ) -//#define PARENT(i) ( ((i)+1)/2 - 1) + +/* MAX_PARENT_IDX is the largest IDX in the smartlist which might have + * children whose indices fit inside an int. + * LEFT_CHILD(MAX_PARENT_IDX) == INT_MAX-2; + * RIGHT_CHILD(MAX_PARENT_IDX) == INT_MAX-1; + * LEFT_CHILD(MAX_PARENT_IDX + 1) == INT_MAX // impossible, see max list size. + */ +#define MAX_PARENT_IDX ((INT_MAX - 2) / 2) +/* If this is true, then i is small enough to potentially have children + * in the smartlist, and it is save to use LEFT_CHILD/RIGHT_CHILD on it. */ +#define IDX_MAY_HAVE_CHILDREN(i) ((i) <= MAX_PARENT_IDX) #define LEFT_CHILD(i) ( 2*(i) + 1 ) #define RIGHT_CHILD(i) ( 2*(i) + 2 ) #define PARENT(i) ( ((i)-1) / 2 ) @@ -876,6 +884,14 @@ smartlist_heapify(smartlist_t *sl, int idx) { while (1) { + if (! IDX_MAY_HAVE_CHILDREN(idx)) { + /* idx is so large that it cannot have any children, since doing so + * would mean the smartlist was over-capacity. Therefore it cannot + * violate the heap property by being greater than a child (since it + * doesn't have any). */ + return; + } + int left_idx = LEFT_CHILD(idx); int best_idx; diff --git a/src/common/crypto.c b/src/common/crypto.c index 06446ba050..7298ec084e 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1327,7 +1327,7 @@ crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out) /** Compute all digests of the DER encoding of <b>pk</b>, and store them * in <b>digests_out</b>. Return 0 on success, -1 on failure. */ int -crypto_pk_get_all_digests(crypto_pk_t *pk, digests_t *digests_out) +crypto_pk_get_common_digests(crypto_pk_t *pk, common_digests_t *digests_out) { unsigned char *buf = NULL; int len; @@ -1335,7 +1335,7 @@ crypto_pk_get_all_digests(crypto_pk_t *pk, digests_t *digests_out) len = i2d_RSAPublicKey(pk->key, &buf); if (len < 0 || buf == NULL) return -1; - if (crypto_digest_all(digests_out, (char*)buf, len) < 0) { + if (crypto_common_digests(digests_out, (char*)buf, len) < 0) { OPENSSL_free(buf); return -1; } @@ -1649,33 +1649,19 @@ crypto_digest512(char *digest, const char *m, size_t len, == -1); } -/** Set the digests_t in <b>ds_out</b> to contain every digest on the +/** Set the common_digests_t in <b>ds_out</b> to contain every digest on the * <b>len</b> bytes in <b>m</b> that we know how to compute. Return 0 on * success, -1 on failure. */ int -crypto_digest_all(digests_t *ds_out, const char *m, size_t len) +crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len) { - int i; tor_assert(ds_out); memset(ds_out, 0, sizeof(*ds_out)); if (crypto_digest(ds_out->d[DIGEST_SHA1], m, len) < 0) return -1; - for (i = DIGEST_SHA256; i < N_DIGEST_ALGORITHMS; ++i) { - switch (i) { - case DIGEST_SHA256: /* FALLSTHROUGH */ - case DIGEST_SHA3_256: - if (crypto_digest256(ds_out->d[i], m, len, i) < 0) - return -1; - break; - case DIGEST_SHA512: - case DIGEST_SHA3_512: /* FALLSTHROUGH */ - if (crypto_digest512(ds_out->d[i], m, len, i) < 0) - return -1; - break; - default: - return -1; - } - } + if (crypto_digest256(ds_out->d[DIGEST_SHA256], m, len, DIGEST_SHA256) < 0) + return -1; + return 0; } diff --git a/src/common/crypto.h b/src/common/crypto.h index 74b88bcd4a..2da7f9e2a1 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -100,8 +100,9 @@ typedef enum { DIGEST_SHA3_512 = 4, } digest_algorithm_t; #define N_DIGEST_ALGORITHMS (DIGEST_SHA3_512+1) +#define N_COMMON_DIGEST_ALGORITHMS (DIGEST_SHA256+1) -/** A set of all the digests we know how to compute, taken on a single +/** A set of all the digests we commonly compute, taken on a single * string. Any digests that are shorter than 512 bits are right-padded * with 0 bits. * @@ -110,8 +111,8 @@ typedef enum { * once. **/ typedef struct { - char d[N_DIGEST_ALGORITHMS][DIGEST512_LEN]; -} digests_t; + char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN]; +} common_digests_t; typedef struct crypto_pk_t crypto_pk_t; typedef struct crypto_cipher_t crypto_cipher_t; @@ -191,7 +192,8 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_t *env, char *to, int crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len); crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len); int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out); -int crypto_pk_get_all_digests(crypto_pk_t *pk, digests_t *digests_out); +int crypto_pk_get_common_digests(crypto_pk_t *pk, + common_digests_t *digests_out); int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space); int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out); @@ -220,7 +222,7 @@ int crypto_digest256(char *digest, const char *m, size_t len, digest_algorithm_t algorithm); int crypto_digest512(char *digest, const char *m, size_t len, digest_algorithm_t algorithm); -int crypto_digest_all(digests_t *ds_out, const char *m, size_t len); +int crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len); struct smartlist_t; void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, const char *prepend, diff --git a/src/common/memarea.c b/src/common/memarea.c index a8e6d455d6..b648c29719 100644 --- a/src/common/memarea.c +++ b/src/common/memarea.c @@ -105,56 +105,32 @@ struct memarea_t { memarea_chunk_t *first; /**< Top of the chunk stack: never NULL. */ }; -/** How many chunks will we put into the freelist before freeing them? */ -#define MAX_FREELIST_LEN 4 -/** The number of memarea chunks currently in our freelist. */ -static int freelist_len=0; -/** A linked list of unused memory area chunks. Used to prevent us from - * spinning in malloc/free loops. */ -static memarea_chunk_t *freelist = NULL; - /** Helper: allocate a new memarea chunk of around <b>chunk_size</b> bytes. */ static memarea_chunk_t * -alloc_chunk(size_t sz, int freelist_ok) +alloc_chunk(size_t sz) { tor_assert(sz < SIZE_T_CEILING); - if (freelist && freelist_ok) { - memarea_chunk_t *res = freelist; - freelist = res->next_chunk; - res->next_chunk = NULL; - --freelist_len; - CHECK_SENTINEL(res); - return res; - } else { - size_t chunk_size = freelist_ok ? CHUNK_SIZE : sz; - memarea_chunk_t *res; - chunk_size += SENTINEL_LEN; - res = tor_malloc(chunk_size); - res->next_chunk = NULL; - res->mem_size = chunk_size - CHUNK_HEADER_SIZE - SENTINEL_LEN; - res->next_mem = res->U_MEM; - tor_assert(res->next_mem+res->mem_size+SENTINEL_LEN == - ((char*)res)+chunk_size); - tor_assert(realign_pointer(res->next_mem) == res->next_mem); - SET_SENTINEL(res); - return res; - } + + size_t chunk_size = sz < CHUNK_SIZE ? CHUNK_SIZE : sz; + memarea_chunk_t *res; + chunk_size += SENTINEL_LEN; + res = tor_malloc(chunk_size); + res->next_chunk = NULL; + res->mem_size = chunk_size - CHUNK_HEADER_SIZE - SENTINEL_LEN; + res->next_mem = res->U_MEM; + tor_assert(res->next_mem+res->mem_size+SENTINEL_LEN == + ((char*)res)+chunk_size); + tor_assert(realign_pointer(res->next_mem) == res->next_mem); + SET_SENTINEL(res); + return res; } -/** Release <b>chunk</b> from a memarea, either by adding it to the freelist - * or by freeing it if the freelist is already too big. */ +/** Release <b>chunk</b> from a memarea. */ static void chunk_free_unchecked(memarea_chunk_t *chunk) { CHECK_SENTINEL(chunk); - if (freelist_len < MAX_FREELIST_LEN) { - ++freelist_len; - chunk->next_chunk = freelist; - freelist = chunk; - chunk->next_mem = chunk->U_MEM; - } else { - tor_free(chunk); - } + tor_free(chunk); } /** Allocate and return new memarea. */ @@ -162,7 +138,7 @@ memarea_t * memarea_new(void) { memarea_t *head = tor_malloc(sizeof(memarea_t)); - head->first = alloc_chunk(CHUNK_SIZE, 1); + head->first = alloc_chunk(CHUNK_SIZE); return head; } @@ -197,19 +173,6 @@ memarea_clear(memarea_t *area) area->first->next_mem = area->first->U_MEM; } -/** Remove all unused memarea chunks from the internal freelist. */ -void -memarea_clear_freelist(void) -{ - memarea_chunk_t *chunk, *next; - freelist_len = 0; - for (chunk = freelist; chunk; chunk = next) { - next = chunk->next_chunk; - tor_free(chunk); - } - freelist = NULL; -} - /** Return true iff <b>p</b> is in a range that has been returned by an * allocation from <b>area</b>. */ int @@ -241,12 +204,12 @@ memarea_alloc(memarea_t *area, size_t sz) if (sz+CHUNK_HEADER_SIZE >= CHUNK_SIZE) { /* This allocation is too big. Stick it in a special chunk, and put * that chunk second in the list. */ - memarea_chunk_t *new_chunk = alloc_chunk(sz+CHUNK_HEADER_SIZE, 0); + memarea_chunk_t *new_chunk = alloc_chunk(sz+CHUNK_HEADER_SIZE); new_chunk->next_chunk = chunk->next_chunk; chunk->next_chunk = new_chunk; chunk = new_chunk; } else { - memarea_chunk_t *new_chunk = alloc_chunk(CHUNK_SIZE, 1); + memarea_chunk_t *new_chunk = alloc_chunk(CHUNK_SIZE); new_chunk->next_chunk = chunk; area->first = chunk = new_chunk; } diff --git a/src/common/memarea.h b/src/common/memarea.h index d14f3a2bae..4b2f3b4836 100644 --- a/src/common/memarea.h +++ b/src/common/memarea.h @@ -18,7 +18,6 @@ char *memarea_strdup(memarea_t *area, const char *s); char *memarea_strndup(memarea_t *area, const char *s, size_t n); void memarea_get_stats(memarea_t *area, size_t *allocated_out, size_t *used_out); -void memarea_clear_freelist(void); void memarea_assert_ok(memarea_t *area); #endif diff --git a/src/common/sandbox.c b/src/common/sandbox.c index d747a87563..c04ed5fe7c 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -427,7 +427,8 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) } rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), - SCMP_CMP_MASKED(1, O_CLOEXEC|O_NONBLOCK|O_NOCTTY, O_RDONLY)); + SCMP_CMP_MASKED(1, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW, + O_RDONLY)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp " "error %d", rc); diff --git a/src/common/timing.c b/src/common/timing.c new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/src/common/timing.c diff --git a/src/common/tortls.c b/src/common/tortls.c index 827abc428d..8f2dc4bf2c 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -685,13 +685,13 @@ MOCK_IMPL(STATIC tor_x509_cert_t *, cert->cert = x509_cert; - crypto_digest_all(&cert->cert_digests, + crypto_common_digests(&cert->cert_digests, (char*)cert->encoded, cert->encoded_len); if ((pkey = X509_get_pubkey(x509_cert)) && (rsa = EVP_PKEY_get1_RSA(pkey))) { crypto_pk_t *pk = crypto_new_pk_from_rsa_(rsa); - crypto_pk_get_all_digests(pk, &cert->pkey_digests); + crypto_pk_get_common_digests(pk, &cert->pkey_digests); cert->pkey_digests_set = 1; crypto_pk_free(pk); EVP_PKEY_free(pkey); @@ -754,7 +754,7 @@ tor_x509_cert_get_der(const tor_x509_cert_t *cert, /** Return a set of digests for the public key in <b>cert</b>, or NULL if this * cert's public key is not one we know how to take the digest of. */ -const digests_t * +const common_digests_t * tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert) { if (cert->pkey_digests_set) @@ -764,7 +764,7 @@ tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert) } /** Return a set of digests for the public key in <b>cert</b>. */ -const digests_t * +const common_digests_t * tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert) { return &cert->cert_digests; diff --git a/src/common/tortls.h b/src/common/tortls.h index 7239eb9fd7..336115ae6b 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -82,8 +82,8 @@ struct tor_x509_cert_t { uint8_t *encoded; size_t encoded_len; unsigned pkey_digests_set : 1; - digests_t cert_digests; - digests_t pkey_digests; + common_digests_t cert_digests; + common_digests_t pkey_digests; }; /** Holds a SSL object and its associated data. Members are only @@ -238,8 +238,10 @@ tor_x509_cert_t *tor_x509_cert_decode(const uint8_t *certificate, size_t certificate_len); void tor_x509_cert_get_der(const tor_x509_cert_t *cert, const uint8_t **encoded_out, size_t *size_out); -const digests_t *tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert); -const digests_t *tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert); +const common_digests_t *tor_x509_cert_get_id_digests( + const tor_x509_cert_t *cert); +const common_digests_t *tor_x509_cert_get_cert_digests( + const tor_x509_cert_t *cert); int tor_tls_get_my_certs(int server, const tor_x509_cert_t **link_cert_out, const tor_x509_cert_t **id_cert_out); diff --git a/src/common/util.c b/src/common/util.c index fda5993edf..488f1b6ca8 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2080,7 +2080,7 @@ check_private_dir(const char *dirname, cpd_check_t check, */ tor_assert(dirname); - /* Open directory. + /* Open directory. * O_NOFOLLOW to ensure that it does not follow symbolic links */ fd = open(sandbox_intern_string(dirname), O_NOFOLLOW); @@ -2122,7 +2122,7 @@ check_private_dir(const char *dirname, cpd_check_t check, if ( fd == -1 ) return -1; - } else if (!(check & CPD_CHECK)) { + } else if (!(check & CPD_CHECK)) { log_warn(LD_FS, "Directory %s does not exist.", dirname); return -1; } diff --git a/src/or/channeltls.c b/src/or/channeltls.c index f0333e8da8..016ef75456 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -1819,7 +1819,8 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) chan->conn->handshake_state->authenticated = 1; { - const digests_t *id_digests = tor_x509_cert_get_id_digests(id_cert); + const common_digests_t *id_digests = + tor_x509_cert_get_id_digests(id_cert); crypto_pk_t *identity_rcvd; if (!id_digests) ERR("Couldn't compute digests for key in ID cert"); @@ -2109,7 +2110,7 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan) { crypto_pk_t *identity_rcvd = tor_tls_cert_get_key(chan->conn->handshake_state->id_cert); - const digests_t *id_digests = + const common_digests_t *id_digests = tor_x509_cert_get_id_digests(chan->conn->handshake_state->id_cert); /* This must exist; we checked key type when reading the cert. */ diff --git a/src/or/connection.c b/src/or/connection.c index a1e9850dc0..0f2b3e356e 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1763,6 +1763,13 @@ connection_connect_log_client_use_ip_version(const connection_t *conn) log_backtrace(LOG_WARN, LD_BUG, "Address came from"); } + /* Bridges are allowed to break IPv4/IPv6 ORPort preferences to connect to + * the node's configured address when ClientPreferIPv6ORPort is auto */ + if (options->UseBridges && conn->type == CONN_TYPE_OR + && options->ClientPreferIPv6ORPort == -1) { + return; + } + /* Check if we couldn't satisfy an address family preference */ if ((!pref_ipv6 && tor_addr_family(&real_addr) == AF_INET6) || (pref_ipv6 && tor_addr_family(&real_addr) == AF_INET)) { diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 29e8153d89..6f40e6a78e 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -2318,7 +2318,7 @@ connection_or_compute_authenticate_cell_body(or_connection_t *conn, { const tor_x509_cert_t *id_cert=NULL, *link_cert=NULL; - const digests_t *my_digests, *their_digests; + const common_digests_t *my_digests, *their_digests; const uint8_t *my_id, *their_id, *client_id, *server_id; if (tor_tls_get_my_certs(server, &link_cert, &id_cert)) goto err; diff --git a/src/or/directory.c b/src/or/directory.c index 6c8b6a248a..627699118c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -972,7 +972,7 @@ directory_command_should_use_begindir(const or_options_t *options, return 0; if (indirection == DIRIND_ONEHOP) if (!fascist_firewall_allows_address_addr(addr, or_port, - FIREWALL_OR_CONNECTION, 0) || + FIREWALL_OR_CONNECTION, 0, 0) || directory_fetches_from_authorities(options)) return 0; /* We're firewalled or are acting like a relay -- also no. */ return 1; @@ -1764,7 +1764,7 @@ load_downloaded_routers(const char *body, smartlist_t *which, added = router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which, descriptor_digests, buf); - if (general) + if (added && general) control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS, count_loading_descriptors_progress()); return added; @@ -1965,7 +1965,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) routers_update_all_from_networkstatus(now, 3); update_microdescs_from_networkstatus(now); update_microdesc_downloads(now); - directory_info_has_arrived(now, 0); + directory_info_has_arrived(now, 0, 0); log_info(LD_DIR, "Successfully loaded consensus."); } @@ -2001,7 +2001,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) * ones got flushed to disk so it's safe to call this on them */ connection_dir_download_cert_failed(conn, status_code); } else { - directory_info_has_arrived(now, 0); + directory_info_has_arrived(now, 0, 0); log_info(LD_DIR, "Successfully loaded certificates from fetch."); } } else { @@ -2115,7 +2115,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) if (load_downloaded_routers(body, which, descriptor_digests, conn->router_purpose, conn->base_.address)) - directory_info_has_arrived(now, 0); + directory_info_has_arrived(now, 0, 0); } } if (which) { /* mark remaining ones as failed */ @@ -2166,8 +2166,11 @@ connection_dir_client_reached_eof(dir_connection_t *conn) /* Mark remaining ones as failed. */ dir_microdesc_download_failed(which, status_code); } - control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS, - count_loading_descriptors_progress()); + if (mds && smartlist_len(mds)) { + control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS, + count_loading_descriptors_progress()); + directory_info_has_arrived(now, 0, 1); + } SMARTLIST_FOREACH(which, char *, cp, tor_free(cp)); smartlist_free(which); smartlist_free(mds); @@ -2363,9 +2366,10 @@ connection_dir_client_reached_eof(dir_connection_t *conn) if (conn->base_.purpose == DIR_PURPOSE_UPLOAD_RENDDESC_V2) { #define SEND_HS_DESC_UPLOAD_FAILED_EVENT(reason) ( \ - control_event_hs_descriptor_upload_failed(conn->identity_digest, \ - conn->rend_data->onion_address, \ - reason) ) + control_event_hs_descriptor_upload_failed( \ + conn->identity_digest, \ + conn->rend_data->onion_address, \ + reason) ) log_info(LD_REND,"Uploaded rendezvous descriptor (status %d " "(%s))", status_code, escaped(reason)); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 3771818457..ee85cebf7e 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1230,7 +1230,7 @@ free_cached_dir_(void *_d) void dirserv_set_cached_consensus_networkstatus(const char *networkstatus, const char *flavor_name, - const digests_t *digests, + const common_digests_t *digests, time_t published) { cached_dir_t *new_networkstatus; @@ -1239,7 +1239,7 @@ dirserv_set_cached_consensus_networkstatus(const char *networkstatus, cached_consensuses = strmap_new(); new_networkstatus = new_cached_dir(tor_strdup(networkstatus), published); - memcpy(&new_networkstatus->digests, digests, sizeof(digests_t)); + memcpy(&new_networkstatus->digests, digests, sizeof(common_digests_t)); old_networkstatus = strmap_set(cached_consensuses, flavor_name, new_networkstatus); if (old_networkstatus) diff --git a/src/or/dirserv.h b/src/or/dirserv.h index d07339bc12..df23450ef9 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -63,9 +63,9 @@ int directory_too_idle_to_fetch_descriptors(const or_options_t *options, cached_dir_t *dirserv_get_consensus(const char *flavor_name); void dirserv_set_cached_consensus_networkstatus(const char *consensus, - const char *flavor_name, - const digests_t *digests, - time_t published); + const char *flavor_name, + const common_digests_t *digests, + time_t published); void dirserv_clear_old_networkstatuses(time_t cutoff); int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key, const char **msg, diff --git a/src/or/dirvote.c b/src/or/dirvote.c index b61b33af79..a81d1a96b1 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -2114,14 +2114,14 @@ networkstatus_add_detached_signatures(networkstatus_t *target, /** Make sure all the digests we know match, and at least one matches. */ { - digests_t *digests = strmap_get(sigs->digests, flavor); + common_digests_t *digests = strmap_get(sigs->digests, flavor); int n_matches = 0; int alg; if (!digests) { *msg_out = "No digests for given consensus flavor"; return -1; } - for (alg = DIGEST_SHA1; alg < N_DIGEST_ALGORITHMS; ++alg) { + for (alg = DIGEST_SHA1; alg < N_COMMON_DIGEST_ALGORITHMS; ++alg) { if (!tor_mem_is_zero(digests->d[alg], DIGEST256_LEN)) { if (fast_memeq(target->digests.d[alg], digests->d[alg], DIGEST256_LEN)) { @@ -2314,7 +2314,7 @@ networkstatus_get_detached_signatures(smartlist_t *consensuses) /* start with SHA256; we don't include SHA1 for anything but the basic * consensus. */ - for (alg = DIGEST_SHA256; alg < N_DIGEST_ALGORITHMS; ++alg) { + for (alg = DIGEST_SHA256; alg < N_COMMON_DIGEST_ALGORITHMS; ++alg) { char d[HEX_DIGEST256_LEN+1]; const char *alg_name = crypto_digest_algorithm_get_name(alg); diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 95d9fecfe4..771a0ef377 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -2121,9 +2121,9 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge) } /* Until we get a descriptor for the bridge, we only know one address for - * it. If we */ + * it. */ if (!fascist_firewall_allows_address_addr(&bridge->addr, bridge->port, - FIREWALL_OR_CONNECTION, 0)) { + FIREWALL_OR_CONNECTION, 0, 0)) { log_notice(LD_CONFIG, "Tried to fetch a descriptor directly from a " "bridge, but that bridge is not reachable through our " "firewall."); @@ -2193,7 +2193,8 @@ fetch_bridge_descriptors(const or_options_t *options, time_t now) if (ask_bridge_directly && !fascist_firewall_allows_address_addr(&bridge->addr, bridge->port, - FIREWALL_OR_CONNECTION, 0)) { + FIREWALL_OR_CONNECTION, 0, + 0)) { log_notice(LD_DIR, "Bridge at '%s' isn't reachable by our " "firewall policy. %s.", fmt_addrport(&bridge->addr, bridge->port), diff --git a/src/or/main.c b/src/or/main.c index 408f2447c1..0b45af9d5d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1002,12 +1002,12 @@ directory_all_unreachable(time_t now) /** This function is called whenever we successfully pull down some new * network statuses or server descriptors. */ void -directory_info_has_arrived(time_t now, int from_cache) +directory_info_has_arrived(time_t now, int from_cache, int suppress_logs) { const or_options_t *options = get_options(); if (!router_have_minimum_dir_info()) { - int quiet = from_cache || + int quiet = suppress_logs || from_cache || directory_too_idle_to_fetch_descriptors(options, now); tor_log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR, "I learned some more directory information, but not enough to " @@ -2391,7 +2391,7 @@ do_main_loop(void) * appropriate.) */ now = time(NULL); - directory_info_has_arrived(now, 1); + directory_info_has_arrived(now, 1, 0); if (server_mode(get_options())) { /* launch cpuworkers. Need to do this *after* we've read the onion key. */ @@ -3100,7 +3100,6 @@ tor_free_all(int postfork) connection_free_all(); connection_edge_free_all(); scheduler_free_all(); - memarea_clear_freelist(); nodelist_free_all(); microdesc_free_all(); ext_orport_free_all(); @@ -3301,6 +3300,8 @@ sandbox_init_filter(void) OPEN_DATADIR2(name, name2 suffix); \ } while (0) + OPEN(options->DataDirectory); + OPEN_DATADIR("keys"); OPEN_DATADIR_SUFFIX("cached-certs", ".tmp"); OPEN_DATADIR_SUFFIX("cached-consensus", ".tmp"); OPEN_DATADIR_SUFFIX("unverified-consensus", ".tmp"); diff --git a/src/or/main.h b/src/or/main.h index 37e93d79d3..74071166e8 100644 --- a/src/or/main.h +++ b/src/or/main.h @@ -48,7 +48,7 @@ MOCK_DECL(void,connection_start_writing,(connection_t *conn)); void connection_stop_reading_from_linked_conn(connection_t *conn); void directory_all_unreachable(time_t now); -void directory_info_has_arrived(time_t now, int from_cache); +void directory_info_has_arrived(time_t now, int from_cache, int suppress_logs); void ip_address_changed(int at_interface); void dns_servers_relaunch_checks(void); diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index f3a8276689..11ee618197 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1526,7 +1526,7 @@ networkstatus_set_current_consensus(const char *consensus, const unsigned dl_certs = !(flags & NSSET_DONT_DOWNLOAD_CERTS); const unsigned accept_obsolete = flags & NSSET_ACCEPT_OBSOLETE; const unsigned require_flavor = flags & NSSET_REQUIRE_FLAVOR; - const digests_t *current_digests = NULL; + const common_digests_t *current_digests = NULL; consensus_waiting_for_certs_t *waiting = NULL; time_t current_valid_after = 0; int free_consensus = 1; /* Free 'c' at the end of the function */ diff --git a/src/or/nodelist.c b/src/or/nodelist.c index 23e9b0e176..91353eea89 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -981,6 +981,9 @@ node_has_ipv6_dirport(const node_t *node) * i) the node_t says that it prefers IPv6 * or * ii) the router has no IPv4 OR address. + * + * If you don't have a node, consider looking it up. + * If there is no node, use fascist_firewall_prefer_ipv6_orport(). */ int node_ipv6_or_preferred(const node_t *node) @@ -1078,6 +1081,8 @@ node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out) * i) the router has no IPv4 Dir address. * or * ii) our preference is for IPv6 Dir addresses. + * + * If there is no node, use fascist_firewall_prefer_ipv6_dirport(). */ int node_ipv6_dir_preferred(const node_t *node) diff --git a/src/or/or.h b/src/or/or.h index f438212b31..0daa9e7025 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1935,7 +1935,7 @@ typedef struct cached_dir_t { size_t dir_len; /**< Length of <b>dir</b> (not counting its NUL). */ size_t dir_z_len; /**< Length of <b>dir_z</b>. */ time_t published; /**< When was this object published. */ - digests_t digests; /**< Digests of this object (networkstatus only) */ + common_digests_t digests; /**< Digests of this object (networkstatus only) */ int refcnt; /**< Reference count for this cached_dir_t. */ } cached_dir_t; @@ -2573,7 +2573,7 @@ typedef struct networkstatus_t { struct authority_cert_t *cert; /**< Vote only: the voter's certificate. */ /** Digests of this document, as signed. */ - digests_t digests; + common_digests_t digests; /** List of router statuses, sorted by identity digest. For a vote, * the elements are vote_routerstatus_t; for a consensus, the elements @@ -4092,8 +4092,8 @@ typedef struct { int ClientUseIPv6; /** If true, prefer an IPv6 OR port over an IPv4 one for entry node * connections. If auto, bridge clients prefer IPv6, and other clients - * prefer IPv4. Use fascist_firewall_prefer_ipv6_orport() instead of - * accessing this value directly. */ + * prefer IPv4. Use node_ipv6_or_preferred() instead of accessing this value + * directly. */ int ClientPreferIPv6ORPort; /** If true, prefer an IPv6 directory port over an IPv4 one for direct * directory connections. If auto, bridge clients prefer IPv6, and other diff --git a/src/or/policies.c b/src/or/policies.c index 179230b88a..5a97c7a134 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -399,20 +399,25 @@ fascist_firewall_allows_address(const tor_addr_t *addr, int pref_only, int pref_ipv6) { const or_options_t *options = get_options(); + const int client_mode = !server_mode(options); if (!addr || tor_addr_is_null(addr) || !port) { return 0; } - if (!server_mode(options)) { - if (tor_addr_family(addr) == AF_INET && - (!options->ClientUseIPv4 || (pref_only && pref_ipv6))) - return 0; + /* Clients stop using IPv4 if it's disabled. In most cases, clients also + * stop using IPv4 if it's not preferred. + * Servers must have IPv4 enabled and preferred. */ + if (tor_addr_family(addr) == AF_INET && client_mode && + (!options->ClientUseIPv4 || (pref_only && pref_ipv6))) { + return 0; + } - /* Bridges can always use IPv6 */ - if (tor_addr_family(addr) == AF_INET6 && - (!fascist_firewall_use_ipv6(options) || (pref_only && !pref_ipv6))) - return 0; + /* Clients and Servers won't use IPv6 unless it's enabled (and in most + * cases, IPv6 must also be preferred before it will be used). */ + if (tor_addr_family(addr) == AF_INET6 && + (!fascist_firewall_use_ipv6(options) || (pref_only && !pref_ipv6))) { + return 0; } return addr_policy_permits_tor_addr(addr, port, @@ -420,6 +425,8 @@ fascist_firewall_allows_address(const tor_addr_t *addr, } /** Is this client configured to use IPv6? + * Use node_ipv6_or/dir_preferred() when checking a specific node and OR/Dir + * port: it supports bridge client per-node IPv6 preferences. */ int fascist_firewall_use_ipv6(const or_options_t *options) @@ -455,17 +462,12 @@ fascist_firewall_prefer_ipv6_impl(const or_options_t *options) } /** Do we prefer to connect to IPv6 ORPorts? + * Use node_ipv6_or_preferred() whenever possible: it supports bridge client + * per-node IPv6 preferences. */ int fascist_firewall_prefer_ipv6_orport(const or_options_t *options) { - /* node->ipv6_preferred is set from fascist_firewall_prefer_ipv6_orport() - * each time the consensus is loaded. - * If our preferences change, we will only reset ipv6_preferred on the node - * when the next consensus is loaded. But the consensus is realoded when the - * configuration changes after a HUP. So as long as the result of this - * function only depends on Tor's options, everything should work ok. - */ int pref_ipv6 = fascist_firewall_prefer_ipv6_impl(options); if (pref_ipv6 >= 0) { @@ -481,6 +483,9 @@ fascist_firewall_prefer_ipv6_orport(const or_options_t *options) } /** Do we prefer to connect to IPv6 DirPorts? + * + * (node_ipv6_dir_preferred() doesn't support bridge client per-node IPv6 + * preferences. There's no reason to use it instead of this function.) */ int fascist_firewall_prefer_ipv6_dirport(const or_options_t *options) @@ -502,26 +507,23 @@ fascist_firewall_prefer_ipv6_dirport(const or_options_t *options) /** Return true iff we think our firewall will let us make a connection to * addr:port. Uses ReachableORAddresses or ReachableDirAddresses based on * fw_connection. - * If pref_only, return false if addr is not in the client's preferred address - * family. + * If pref_only is true, return true if addr is in the client's preferred + * address family, which is IPv6 if pref_ipv6 is true, and IPv4 otherwise. + * If pref_only is false, ignore pref_ipv6, and return true if addr is allowed. */ int fascist_firewall_allows_address_addr(const tor_addr_t *addr, uint16_t port, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { - const or_options_t *options = get_options(); - if (fw_connection == FIREWALL_OR_CONNECTION) { return fascist_firewall_allows_address(addr, port, reachable_or_addr_policy, - pref_only, - fascist_firewall_prefer_ipv6_orport(options)); + pref_only, pref_ipv6); } else if (fw_connection == FIREWALL_DIR_CONNECTION) { return fascist_firewall_allows_address(addr, port, reachable_dir_addr_policy, - pref_only, - fascist_firewall_prefer_ipv6_dirport(options)); + pref_only, pref_ipv6); } else { log_warn(LD_BUG, "Bad firewall_connection_t value %d.", fw_connection); @@ -532,57 +534,58 @@ fascist_firewall_allows_address_addr(const tor_addr_t *addr, uint16_t port, /** Return true iff we think our firewall will let us make a connection to * addr:port (ap). Uses ReachableORAddresses or ReachableDirAddresses based on * fw_connection. - * If pref_only, return false if addr is not in the client's preferred address - * family. + * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr(). */ -int +static int fascist_firewall_allows_address_ap(const tor_addr_port_t *ap, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { tor_assert(ap); return fascist_firewall_allows_address_addr(&ap->addr, ap->port, - fw_connection, pref_only); + fw_connection, pref_only, + pref_ipv6); } /* Return true iff we think our firewall will let us make a connection to * ipv4h_or_addr:ipv4_or_port. ipv4h_or_addr is interpreted in host order. * Uses ReachableORAddresses or ReachableDirAddresses based on * fw_connection. - * If pref_only, return false if addr is not in the client's preferred address - * family. */ -int + * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr(). + */ +static int fascist_firewall_allows_address_ipv4h(uint32_t ipv4h_or_addr, uint16_t ipv4_or_port, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { tor_addr_t ipv4_or_addr; tor_addr_from_ipv4h(&ipv4_or_addr, ipv4h_or_addr); return fascist_firewall_allows_address_addr(&ipv4_or_addr, ipv4_or_port, - fw_connection, pref_only); + fw_connection, pref_only, + pref_ipv6); } /** Return true iff we think our firewall will let us make a connection to * ipv4h_addr/ipv6_addr. Uses ipv4_orport/ipv6_orport/ReachableORAddresses or * ipv4_dirport/ipv6_dirport/ReachableDirAddresses based on IPv4/IPv6 and * <b>fw_connection</b>. - * If pref_only, return false if addr is not in the client's preferred address - * family. */ + * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr(). + */ static int fascist_firewall_allows_base(uint32_t ipv4h_addr, uint16_t ipv4_orport, uint16_t ipv4_dirport, const tor_addr_t *ipv6_addr, uint16_t ipv6_orport, uint16_t ipv6_dirport, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { if (fascist_firewall_allows_address_ipv4h(ipv4h_addr, (fw_connection == FIREWALL_OR_CONNECTION ? ipv4_orport : ipv4_dirport), fw_connection, - pref_only)) { + pref_only, pref_ipv6)) { return 1; } @@ -591,18 +594,18 @@ fascist_firewall_allows_base(uint32_t ipv4h_addr, uint16_t ipv4_orport, ? ipv6_orport : ipv6_dirport), fw_connection, - pref_only)) { + pref_only, pref_ipv6)) { return 1; } return 0; } -/** Like fascist_firewall_allows_ri, but doesn't consult the node. */ +/** Like fascist_firewall_allows_base(), but takes ri. */ static int fascist_firewall_allows_ri_impl(const routerinfo_t *ri, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { if (!ri) { return 0; @@ -611,14 +614,15 @@ fascist_firewall_allows_ri_impl(const routerinfo_t *ri, /* Assume IPv4 and IPv6 DirPorts are the same */ return fascist_firewall_allows_base(ri->addr, ri->or_port, ri->dir_port, &ri->ipv6_addr, ri->ipv6_orport, - ri->dir_port, fw_connection, pref_only); + ri->dir_port, fw_connection, pref_only, + pref_ipv6); } /** Like fascist_firewall_allows_rs, but doesn't consult the node. */ static int fascist_firewall_allows_rs_impl(const routerstatus_t *rs, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { if (!rs) { return 0; @@ -627,16 +631,15 @@ fascist_firewall_allows_rs_impl(const routerstatus_t *rs, /* Assume IPv4 and IPv6 DirPorts are the same */ return fascist_firewall_allows_base(rs->addr, rs->or_port, rs->dir_port, &rs->ipv6_addr, rs->ipv6_orport, - rs->dir_port, fw_connection, pref_only); + rs->dir_port, fw_connection, pref_only, + pref_ipv6); } -/** Return true iff we think our firewall will let us make a connection to - * <b>rs</b> on either its IPv4 or IPv6 address. Uses - * or_port/ipv6_orport/ReachableORAddresses or dir_port/ReachableDirAddresses - * based on IPv4/IPv6 and <b>fw_connection</b>. - * If pref_only, return false if addr is not in the client's preferred address - * family. - * Consults the corresponding node if the addresses in rs are not permitted. */ +/** Like fascist_firewall_allows_base(), but takes rs. + * Consults the corresponding node, then falls back to rs if node is NULL. + * This should only happen when there's no valid consensus, and rs doesn't + * correspond to a bridge client's bridge. + */ int fascist_firewall_allows_rs(const routerstatus_t *rs, firewall_connection_t fw_connection, int pref_only) @@ -645,20 +648,32 @@ fascist_firewall_allows_rs(const routerstatus_t *rs, return 0; } - /* Assume IPv4 and IPv6 DirPorts are the same */ - if (fascist_firewall_allows_rs_impl(rs, fw_connection, pref_only)) { - return 1; - } else { - const node_t *node = node_get_by_id(rs->identity_digest); + const node_t *node = node_get_by_id(rs->identity_digest); + + if (node) { return fascist_firewall_allows_node(node, fw_connection, pref_only); + } else { + /* There's no node-specific IPv6 preference, so use the generic IPv6 + * preference instead. */ + const or_options_t *options = get_options(); + int pref_ipv6 = (fw_connection == FIREWALL_OR_CONNECTION + ? fascist_firewall_prefer_ipv6_orport(options) + : fascist_firewall_prefer_ipv6_dirport(options)); + + return fascist_firewall_allows_rs_impl(rs, fw_connection, pref_only, + pref_ipv6); } } -/** Like fascist_firewall_allows_md, but doesn't consult the node. */ +/** Return true iff we think our firewall will let us make a connection to + * ipv6_addr:ipv6_orport based on ReachableORAddresses. + * If <b>fw_connection</b> is FIREWALL_DIR_CONNECTION, returns 0. + * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr(). + */ static int fascist_firewall_allows_md_impl(const microdesc_t *md, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { if (!md) { return 0; @@ -671,17 +686,12 @@ fascist_firewall_allows_md_impl(const microdesc_t *md, /* Also can't check IPv4, doesn't have that either */ return fascist_firewall_allows_address_addr(&md->ipv6_addr, md->ipv6_orport, - fw_connection, pref_only); + fw_connection, pref_only, + pref_ipv6); } -/** Return true iff we think our firewall will let us make a connection to - * <b>node</b>: - * - if <b>preferred</b> is true, on its preferred address, - * - if not, on either its IPv4 or IPv6 address. - * Uses or_port/ipv6_orport/ReachableORAddresses or - * dir_port/ReachableDirAddresses based on IPv4/IPv6 and <b>fw_connection</b>. - * If pref_only, return false if addr is not in the client's preferred address - * family. */ +/** Like fascist_firewall_allows_base(), but takes node, and looks up pref_ipv6 + * from node_ipv6_or/dir_preferred(). */ int fascist_firewall_allows_node(const node_t *node, firewall_connection_t fw_connection, @@ -693,18 +703,24 @@ fascist_firewall_allows_node(const node_t *node, node_assert_ok(node); + const int pref_ipv6 = (fw_connection == FIREWALL_OR_CONNECTION + ? node_ipv6_or_preferred(node) + : node_ipv6_dir_preferred(node)); + /* Sometimes, the rs is missing the IPv6 address info, and we need to go * all the way to the md */ if (node->ri && fascist_firewall_allows_ri_impl(node->ri, fw_connection, - pref_only)) { + pref_only, pref_ipv6)) { return 1; } else if (node->rs && fascist_firewall_allows_rs_impl(node->rs, fw_connection, - pref_only)) { + pref_only, + pref_ipv6)) { return 1; } else if (node->md && fascist_firewall_allows_md_impl(node->md, fw_connection, - pref_only)) { + pref_only, + pref_ipv6)) { return 1; } else { /* If we know nothing, assume it's unreachable, we'll never get an address @@ -713,12 +729,7 @@ fascist_firewall_allows_node(const node_t *node, } } -/** Return true iff we think our firewall will let us make a connection to - * <b>ds</b> on either its IPv4 or IPv6 address. Uses ReachableORAddresses or - * ReachableDirAddresses based on <b>fw_connection</b> (some directory - * connections are tunneled over ORPorts). - * If pref_only, return false if addr is not in the client's preferred address - * family. */ +/** Like fascist_firewall_allows_rs(), but takes ds. */ int fascist_firewall_allows_dir_server(const dir_server_t *ds, firewall_connection_t fw_connection, @@ -731,8 +742,8 @@ fascist_firewall_allows_dir_server(const dir_server_t *ds, /* A dir_server_t always has a fake_status. As long as it has the same * addresses/ports in both fake_status and dir_server_t, this works fine. * (See #17867.) - * This function relies on fascist_firewall_allows_rs looking up the node on - * failure, because it will get the latest info for the relay. */ + * This function relies on fascist_firewall_choose_address_rs looking up the + * node if it can, because that will get the latest info for the relay. */ return fascist_firewall_allows_rs(&ds->fake_status, fw_connection, pref_only); } @@ -741,23 +752,25 @@ fascist_firewall_allows_dir_server(const dir_server_t *ds, * choose one based on want_a and return it. * Otherwise, return whichever is allowed. * Otherwise, return NULL. - * If pref_only, only return an address if it's in the client's preferred - * address family. */ + * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr(). + */ static const tor_addr_port_t * fascist_firewall_choose_address_impl(const tor_addr_port_t *a, const tor_addr_port_t *b, int want_a, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { const tor_addr_port_t *use_a = NULL; const tor_addr_port_t *use_b = NULL; - if (fascist_firewall_allows_address_ap(a, fw_connection, pref_only)) { + if (fascist_firewall_allows_address_ap(a, fw_connection, pref_only, + pref_ipv6)) { use_a = a; } - if (fascist_firewall_allows_address_ap(b, fw_connection, pref_only)) { + if (fascist_firewall_allows_address_ap(b, fw_connection, pref_only, + pref_ipv6)) { use_b = b; } @@ -779,17 +792,17 @@ fascist_firewall_choose_address_impl(const tor_addr_port_t *a, * choose one based on want_a and return it. * - Otherwise, return whichever is preferred. * Otherwise, return NULL. */ -const tor_addr_port_t * +STATIC const tor_addr_port_t * fascist_firewall_choose_address(const tor_addr_port_t *a, const tor_addr_port_t *b, int want_a, firewall_connection_t fw_connection, - int pref_only) + int pref_only, int pref_ipv6) { const tor_addr_port_t *pref = fascist_firewall_choose_address_impl( a, b, want_a, fw_connection, - 1); + 1, pref_ipv6); if (pref_only || pref) { /* If there is a preferred address, use it. If we can only use preferred * addresses, and neither address is preferred, pref will be NULL, and we @@ -799,7 +812,7 @@ fascist_firewall_choose_address(const tor_addr_port_t *a, /* If there's no preferred address, and we can return addresses that are * not preferred, use an address that's allowed */ return fascist_firewall_choose_address_impl(a, b, want_a, fw_connection, - 0); + 0, pref_ipv6); } } @@ -810,6 +823,8 @@ fascist_firewall_choose_address(const tor_addr_port_t *a, * <b>fw_connection</b>. * If pref_only, only choose preferred addresses. In either case, choose * a preferred address before an address that's not preferred. + * If both addresses could be chosen (they are both preferred or both allowed) + * choose IPv6 if pref_ipv6 is true, otherwise choose IPv4. * If neither address is chosen, return 0, else return 1. */ static int fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr, @@ -820,14 +835,11 @@ fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr, uint16_t ipv6_dirport, firewall_connection_t fw_connection, int pref_only, + int pref_ipv6, tor_addr_port_t* ap) { const tor_addr_port_t *result = NULL; - /* This argument is ignored as long as the address pair is IPv4/IPv6, - * because we always have a preference in a client. - * For bridge clients, this selects the preferred address, which was - * previously IPv6 (if a bridge has both), so we keep that behaviour. */ - const int bridge_client_prefer_ipv4 = 0; + const int want_ipv4 = !pref_ipv6; tor_assert(ipv6_addr); tor_assert(ap); @@ -845,8 +857,9 @@ fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr, : ipv6_dirport); result = fascist_firewall_choose_address(&ipv4_ap, &ipv6_ap, - bridge_client_prefer_ipv4, - fw_connection, pref_only); + want_ipv4, + fw_connection, pref_only, + pref_ipv6); if (result) { tor_addr_copy(&ap->addr, &result->addr); @@ -857,7 +870,7 @@ fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr, } } -/** Like fascist_firewall_choose_address_base, but takes a host-order IPv4 +/** Like fascist_firewall_choose_address_base(), but takes a host-order IPv4 * address as the first parameter. */ static int fascist_firewall_choose_address_ipv4h(uint32_t ipv4h_addr, @@ -868,6 +881,7 @@ fascist_firewall_choose_address_ipv4h(uint32_t ipv4h_addr, uint16_t ipv6_dirport, firewall_connection_t fw_connection, int pref_only, + int pref_ipv6, tor_addr_port_t* ap) { tor_addr_t ipv4_addr; @@ -875,34 +889,15 @@ fascist_firewall_choose_address_ipv4h(uint32_t ipv4h_addr, return fascist_firewall_choose_address_base(&ipv4_addr, ipv4_orport, ipv4_dirport, ipv6_addr, ipv6_orport, ipv6_dirport, - fw_connection, pref_only, ap); -} - -#define IPV6_OR_LOOKUP(r, identity_digest, ipv6_or_ap) \ - STMT_BEGIN \ - if (!(r)->ipv6_orport || tor_addr_is_null(&(r)->ipv6_addr)) { \ - const node_t *node = node_get_by_id((identity_digest)); \ - if (node) { \ - node_get_pref_ipv6_orport(node, &(ipv6_or_ap)); \ - } else { \ - tor_addr_make_null(&(ipv6_or_ap).addr, AF_INET6); \ - (ipv6_or_ap).port = 0; \ - } \ - } else { \ - tor_addr_copy(&(ipv6_or_ap).addr, &(r)->ipv6_addr); \ - (ipv6_or_ap).port = (r)->ipv6_orport; \ - } \ - STMT_END - -/** Copy an address and port from <b>rs</b> into <b>ap</b> that we think our - * firewall will let us connect to. Uses ipv4h_addr/ipv6_addr and - * ipv4_orport/ipv6_orport/ReachableORAddresses or - * ipv4_dirport/ipv6_dirport/ReachableDirAddresses based on IPv4/IPv6 and - * <b>fw_connection</b>. - * If pref_only, only choose preferred addresses. In either case, choose - * a preferred address before an address that's not preferred. - * If neither address is chosen, return 0, else return 1. - * Consults the corresponding node if the addresses in rs are not valid. */ + fw_connection, pref_only, + pref_ipv6, ap); +} + +/** Like fascist_firewall_choose_address_base(), but takes <b>rs</b>. + * Consults the corresponding node, then falls back to rs if node is NULL. + * This should only happen when there's no valid consensus, and rs doesn't + * correspond to a bridge client's bridge. + */ int fascist_firewall_choose_address_rs(const routerstatus_t *rs, firewall_connection_t fw_connection, @@ -914,32 +909,37 @@ fascist_firewall_choose_address_rs(const routerstatus_t *rs, tor_assert(ap); - /* Don't do the lookup if the IPv6 address/port in rs is OK. - * If it's OK, assume the dir_port is also OK. */ - tor_addr_port_t ipv6_or_ap; - IPV6_OR_LOOKUP(rs, rs->identity_digest, ipv6_or_ap); - - /* Assume IPv4 and IPv6 DirPorts are the same. - * Assume the IPv6 OR and Dir addresses are the same. */ - return fascist_firewall_choose_address_ipv4h(rs->addr, - rs->or_port, - rs->dir_port, - &ipv6_or_ap.addr, - ipv6_or_ap.port, - rs->dir_port, - fw_connection, - pref_only, - ap); -} - -/** Copy an address and port from <b>node</b> into <b>ap</b> that we think our - * firewall will let us connect to. Uses ipv4h_addr/ipv6_addr and - * ipv4_orport/ipv6_orport/ReachableORAddresses or - * ipv4_dirport/ipv6_dirport/ReachableDirAddresses based on IPv4/IPv6 and - * <b>fw_connection</b>. - * If pref_only, only choose preferred addresses. In either case, choose - * a preferred address before an address that's not preferred. - * If neither address is chosen, return 0, else return 1. */ + const node_t *node = node_get_by_id(rs->identity_digest); + + if (node) { + return fascist_firewall_choose_address_node(node, fw_connection, pref_only, + ap); + } else { + /* There's no node-specific IPv6 preference, so use the generic IPv6 + * preference instead. */ + const or_options_t *options = get_options(); + int pref_ipv6 = (fw_connection == FIREWALL_OR_CONNECTION + ? fascist_firewall_prefer_ipv6_orport(options) + : fascist_firewall_prefer_ipv6_dirport(options)); + + /* Assume IPv4 and IPv6 DirPorts are the same. + * Assume the IPv6 OR and Dir addresses are the same. */ + return fascist_firewall_choose_address_ipv4h(rs->addr, + rs->or_port, + rs->dir_port, + &rs->ipv6_addr, + rs->ipv6_orport, + rs->dir_port, + fw_connection, + pref_only, + pref_ipv6, + ap); + } +} + +/** Like fascist_firewall_choose_address_base(), but takes <b>node</b>, and + * looks up the node's IPv6 preference rather than taking an argument + * for pref_ipv6. */ int fascist_firewall_choose_address_node(const node_t *node, firewall_connection_t fw_connection, @@ -951,6 +951,10 @@ fascist_firewall_choose_address_node(const node_t *node, node_assert_ok(node); + const int pref_ipv6_node = (fw_connection == FIREWALL_OR_CONNECTION + ? node_ipv6_or_preferred(node) + : node_ipv6_dir_preferred(node)); + tor_addr_port_t ipv4_or_ap; node_get_prim_orport(node, &ipv4_or_ap); tor_addr_port_t ipv4_dir_ap; @@ -970,21 +974,16 @@ fascist_firewall_choose_address_node(const node_t *node, ipv6_dir_ap.port, fw_connection, pref_only, + pref_ipv6_node, ap); } -/** Copy an address and port from <b>ds</b> into <b>ap</b> that we think our - * firewall will let us connect to. Uses ipv4h_addr/ipv6_addr and - * ipv4_orport/ipv6_orport/ReachableORAddresses or - * ipv4_dirport/ipv6_dirport/ReachableDirAddresses based on IPv4/IPv6 and - * <b>fw_connection</b>. - * If pref_only, only choose preferred addresses. In either case, choose - * a preferred address before an address that's not preferred. - * If neither address is chosen, return 0, else return 1. */ +/** Like fascist_firewall_choose_address_rs(), but takes <b>ds</b>. */ int fascist_firewall_choose_address_dir_server(const dir_server_t *ds, firewall_connection_t fw_connection, - int pref_only, tor_addr_port_t *ap) + int pref_only, + tor_addr_port_t *ap) { if (!ds) { return 0; @@ -994,8 +993,7 @@ fascist_firewall_choose_address_dir_server(const dir_server_t *ds, * addresses/ports in both fake_status and dir_server_t, this works fine. * (See #17867.) * This function relies on fascist_firewall_choose_address_rs looking up the - * addresses from the node if it can, because that will get the latest info - * for the relay. */ + * node if it can, because that will get the latest info for the relay. */ return fascist_firewall_choose_address_rs(&ds->fake_status, fw_connection, pref_only, ap); } diff --git a/src/or/policies.h b/src/or/policies.h index 65f10e2ed7..757d2f31df 100644 --- a/src/or/policies.h +++ b/src/or/policies.h @@ -35,16 +35,11 @@ int fascist_firewall_use_ipv6(const or_options_t *options); int fascist_firewall_prefer_ipv6_orport(const or_options_t *options); int fascist_firewall_prefer_ipv6_dirport(const or_options_t *options); -int fascist_firewall_allows_address_addr(const tor_addr_t *addr, uint16_t port, +int fascist_firewall_allows_address_addr(const tor_addr_t *addr, + uint16_t port, firewall_connection_t fw_connection, - int pref_only); -int fascist_firewall_allows_address_ap(const tor_addr_port_t *ap, - firewall_connection_t fw_connection, - int pref_only); -int fascist_firewall_allows_address_ipv4h(uint32_t ipv4h_or_addr, - uint16_t ipv4_or_port, - firewall_connection_t fw_connection, - int pref_only); + int pref_only, int pref_ipv6); + int fascist_firewall_allows_rs(const routerstatus_t *rs, firewall_connection_t fw_connection, int pref_only); @@ -55,12 +50,6 @@ int fascist_firewall_allows_dir_server(const dir_server_t *ds, firewall_connection_t fw_connection, int pref_only); -const tor_addr_port_t * fascist_firewall_choose_address( - const tor_addr_port_t *a, - const tor_addr_port_t *b, - int want_a, - firewall_connection_t fw_connection, - int pref_only); int fascist_firewall_choose_address_rs(const routerstatus_t *rs, firewall_connection_t fw_connection, int pref_only, tor_addr_port_t* ap); @@ -69,7 +58,7 @@ int fascist_firewall_choose_address_node(const node_t *node, int pref_only, tor_addr_port_t* ap); int fascist_firewall_choose_address_dir_server(const dir_server_t *ds, firewall_connection_t fw_connection, - int pref_only, tor_addr_port_t* ap); + int pref_only, tor_addr_port_t* ap); int dir_policy_permits_address(const tor_addr_t *addr); int socks_policy_permits_address(const tor_addr_t *addr); @@ -140,6 +129,13 @@ STATIC int fascist_firewall_allows_address(const tor_addr_t *addr, uint16_t port, smartlist_t *firewall_policy, int pref_only, int pref_ipv6); +STATIC const tor_addr_port_t * fascist_firewall_choose_address( + const tor_addr_port_t *a, + const tor_addr_port_t *b, + int want_a, + firewall_connection_t fw_connection, + int pref_only, int pref_ipv6); + #endif #endif diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c index d88bfca13a..210178dc1d 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -927,7 +927,7 @@ generate_ed_link_cert(const or_options_t *options, time_t now) return -1; } - const digests_t *digests = tor_x509_cert_get_cert_digests(link); + const common_digests_t *digests = tor_x509_cert_get_cert_digests(link); if (link_cert_cert && ! EXPIRES_SOON(link_cert_cert, options->TestingLinkKeySlop) && @@ -972,7 +972,7 @@ should_make_new_ed_keys(const or_options_t *options, const time_t now) if (tor_tls_get_my_certs(1, &link, &id) < 0 || link == NULL) return 1; - const digests_t *digests = tor_x509_cert_get_cert_digests(link); + const common_digests_t *digests = tor_x509_cert_get_cert_digests(link); if (!fast_memeq(digests->d[DIGEST_SHA256], link_cert_cert->signed_key.pubkey, diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 13ef081064..d740b0d4ae 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1566,14 +1566,14 @@ router_picked_poor_directory_log(const routerstatus_t *rs) } else if (!fascist_firewall_allows_rs(rs, FIREWALL_OR_CONNECTION, 1) && !fascist_firewall_allows_rs(rs, FIREWALL_DIR_CONNECTION, 1) ) { - log_warn(LD_BUG, "Selected a directory %s with non-preferred OR and Dir " + log_info(LD_BUG, "Selected a directory %s with non-preferred OR and Dir " "addresses for launching a connection: " "IPv4 %s OR %d Dir %d IPv6 %s OR %d Dir %d", routerstatus_describe(rs), fmt_addr32(rs->addr), rs->or_port, rs->dir_port, fmt_addr(&rs->ipv6_addr), rs->ipv6_orport, rs->dir_port); - log_backtrace(LOG_WARN, LD_BUG, "Node search initiated by"); + log_backtrace(LOG_INFO, LD_BUG, "Node search initiated by"); } } diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 3be43dcb8e..43c30a19ee 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -538,7 +538,7 @@ static int router_get_hash_impl(const char *s, size_t s_len, char *digest, char end_char, digest_algorithm_t alg); static int router_get_hashes_impl(const char *s, size_t s_len, - digests_t *digests, + common_digests_t *digests, const char *start_str, const char *end_str, char end_char); static void token_clear(directory_token_t *tok); @@ -638,7 +638,7 @@ router_get_router_hash(const char *s, size_t s_len, char *digest) /** Set <b>digests</b> to all the digests of the consensus document in * <b>s</b> */ int -router_get_networkstatus_v3_hashes(const char *s, digests_t *digests) +router_get_networkstatus_v3_hashes(const char *s, common_digests_t *digests) { return router_get_hashes_impl(s,strlen(s),digests, "network-status-version", @@ -2847,7 +2847,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, smartlist_t *rs_tokens = NULL, *footer_tokens = NULL; networkstatus_voter_info_t *voter = NULL; networkstatus_t *ns = NULL; - digests_t ns_digests; + common_digests_t ns_digests; const char *cert, *end_of_header, *end_of_footer, *s_dup = s; directory_token_t *tok; int ok; @@ -3443,15 +3443,16 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out, return ns; } -/** Return the digests_t that holds the digests of the +/** Return the common_digests_t that holds the digests of the * <b>flavor_name</b>-flavored networkstatus according to the detached - * signatures document <b>sigs</b>, allocating a new digests_t as neeeded. */ -static digests_t * + * signatures document <b>sigs</b>, allocating a new common_digests_t as + * neeeded. */ +static common_digests_t * detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name) { - digests_t *d = strmap_get(sigs->digests, flavor_name); + common_digests_t *d = strmap_get(sigs->digests, flavor_name); if (!d) { - d = tor_malloc_zero(sizeof(digests_t)); + d = tor_malloc_zero(sizeof(common_digests_t)); strmap_set(sigs->digests, flavor_name, d); } return d; @@ -3459,7 +3460,7 @@ detached_get_digests(ns_detached_signatures_t *sigs, const char *flavor_name) /** Return the list of signatures of the <b>flavor_name</b>-flavored * networkstatus according to the detached signatures document <b>sigs</b>, - * allocating a new digests_t as neeeded. */ + * allocating a new common_digests_t as neeeded. */ static smartlist_t * detached_get_signatures(ns_detached_signatures_t *sigs, const char *flavor_name) @@ -3481,7 +3482,7 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos) * networkstatus_parse_vote_from_string(). */ directory_token_t *tok; memarea_t *area = NULL; - digests_t *digests; + common_digests_t *digests; smartlist_t *tokens = smartlist_new(); ns_detached_signatures_t *sigs = @@ -4444,7 +4445,7 @@ router_get_hash_impl(const char *s, size_t s_len, char *digest, /** As router_get_hash_impl, but compute all hashes. */ static int -router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests, +router_get_hashes_impl(const char *s, size_t s_len, common_digests_t *digests, const char *start_str, const char *end_str, char end_c) { @@ -4453,7 +4454,7 @@ router_get_hashes_impl(const char *s, size_t s_len, digests_t *digests, &start,&end)<0) return -1; - if (crypto_digest_all(digests, start, end-start)) { + if (crypto_common_digests(digests, start, end-start)) { log_warn(LD_BUG,"couldn't compute digests"); return -1; } diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 99fd52866c..723d5d8945 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -14,7 +14,8 @@ int router_get_router_hash(const char *s, size_t s_len, char *digest); int router_get_dir_hash(const char *s, char *digest); -int router_get_networkstatus_v3_hashes(const char *s, digests_t *digests); +int router_get_networkstatus_v3_hashes(const char *s, + common_digests_t *digests); int router_get_extrainfo_hash(const char *s, size_t s_len, char *digest); #define DIROBJ_MAX_SIG_LEN 256 char *router_get_dirobj_signature(const char *digest, diff --git a/src/test/test_address.c b/src/test/test_address.c index 3b17b23571..748dfc5a68 100644 --- a/src/test/test_address.c +++ b/src/test/test_address.c @@ -297,7 +297,9 @@ test_address_get_if_addrs_ifaddrs(void *arg) } done: - SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t)); + if (results) { + SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t)); + } smartlist_free(results); return; } diff --git a/src/test/test_config.c b/src/test/test_config.c index 6be503abc5..75786abb0c 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -3752,6 +3752,7 @@ test_config_parse_port_config__listenaddress(void *data) // Port lines for the same portname ret = parse_port_config(NULL, config_port1, config_listen_address, "DNS", 0, NULL, 0, 0); + tt_int_op(ret, OP_EQ, -1); // Test case when we have a listen address, no default port and allow @@ -3842,14 +3843,16 @@ test_config_parse_port_config__listenaddress(void *data) tt_int_op(ret, OP_EQ, 0); done: - tor_free(config_listen_address); - tor_free(config_listen_address2); - tor_free(config_listen_address3); - tor_free(config_port1); - tor_free(config_port2); - tor_free(config_port3); - tor_free(config_port4); - tor_free(config_port5); + config_free_lines(config_listen_address); + config_free_lines(config_listen_address2); + config_free_lines(config_listen_address3); + config_free_lines(config_port1); + /* 2 was linked from 1. */ + config_free_lines(config_port3); + config_free_lines(config_port4); + config_free_lines(config_port5); + if (slout) + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_free(slout); } @@ -3895,6 +3898,7 @@ test_config_parse_port_config__ports__no_ports_given(void *data) tt_int_op(smartlist_len(slout), OP_EQ, 0); // Test with defaultport, with defaultaddress and out, adds a new port cfg + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); ret = parse_port_config(slout, NULL, NULL, "DNS", 0, "127.0.0.2", 42, 0); tt_int_op(ret, OP_EQ, 0); @@ -3905,6 +3909,7 @@ test_config_parse_port_config__ports__no_ports_given(void *data) // Test with defaultport, with defaultaddress and out, adds a new port cfg // for a unix address + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); ret = parse_port_config(slout, NULL, NULL, "DNS", 0, "/foo/bar/unixdomain", 42, CL_PORT_IS_UNIXSOCKET); @@ -3916,6 +3921,8 @@ test_config_parse_port_config__ports__no_ports_given(void *data) tt_str_op(port_cfg->unix_addr, OP_EQ, "/foo/bar/unixdomain"); done: + if (slout) + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_free(slout); } @@ -3952,6 +3959,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(ret, OP_EQ, -1); // Test valid unix domain + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", CONN_TYPE_AP_LISTENER, NULL, 0, 0); @@ -3979,6 +3987,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with no ipv4 but take ipv6 (for unix domain sockets, this // makes no sense - it should be fixed) config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "unix:/tmp/foo/bar " "NoIPv4Traffic IPv6Traffic"); @@ -3998,6 +4007,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with both ipv4 and ipv6 (for unix domain sockets, // this makes no sense - it should be fixed) config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "unix:/tmp/foo/bar " "IPv4Traffic IPv6Traffic"); @@ -4037,6 +4047,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with only a port and isolate destination port config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IsolateDestPort"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4049,6 +4060,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with a negative isolate destination port, and plural config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 NoIsolateDestPorts"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4061,6 +4073,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with isolate destination address config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IsolateDestAddr"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4073,6 +4086,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with isolate socks AUTH config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IsolateSOCKSAuth"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4085,6 +4099,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with isolate client protocol config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IsolateClientProtocol"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4097,6 +4112,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with isolate client address config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IsolateClientAddr"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4116,6 +4132,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with no isolate socks AUTH config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 NoIsolateSOCKSAuth"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4127,6 +4144,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with prefer ipv6 config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IPv6Traffic PreferIPv6"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", @@ -4139,6 +4157,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with cache ipv4 DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 CacheIPv4DNS"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4151,6 +4170,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with cache ipv6 DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 CacheIPv6DNS"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4163,6 +4183,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with no cache ipv4 DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 NoCacheIPv4DNS"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4175,6 +4196,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with cache DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 CacheDNS"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4187,6 +4209,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with use cached ipv4 DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 UseIPv4Cache"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4199,6 +4222,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with use cached ipv6 DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 UseIPv6Cache"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4211,6 +4235,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with use cached DNS config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 UseDNSCache"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4223,6 +4248,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with not preferring ipv6 automap config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 NoPreferIPv6Automap"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4234,6 +4260,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with prefer SOCKS no auth config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 PreferSOCKSNoAuth"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4246,6 +4273,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test failure with both a zero port and a non-zero port config_free_lines(config_port_invalid); config_port_invalid = NULL; config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "0"); config_port_valid = mock_config_line("DNSPort", "42"); @@ -4255,6 +4283,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(ret, OP_EQ, -1); // Test success with warn non-local control + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", CONN_TYPE_CONTROL_LISTENER, "127.0.0.42", 0, @@ -4262,6 +4291,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(ret, OP_EQ, 0); // Test success with warn non-local listener + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", CONN_TYPE_EXT_OR_LISTENER, "127.0.0.42", 0, @@ -4269,6 +4299,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(ret, OP_EQ, 0); // Test success with warn non-local other + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, "127.0.0.42", 0, CL_PORT_WARN_NONLOCAL); @@ -4280,7 +4311,9 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(ret, OP_EQ, 0); // Test success with both ipv4 and ipv6 but without stream options - config_free_lines(config_port_valid); config_port_valid = NULL; + config_free_lines(config_port_invalid); config_port_invalid = NULL; + config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 IPv4Traffic " "IPv6Traffic"); @@ -4295,7 +4328,8 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0); // Test failure for a SessionGroup argument with invalid value - config_free_lines(config_port_valid); config_port_valid = NULL; + config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=invalid"); ret = parse_port_config(slout, config_port_invalid, NULL, "DNS", 0, @@ -4307,6 +4341,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test failure for a SessionGroup argument with valid value but with stream // options allowed config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123"); ret = parse_port_config(slout, config_port_invalid, NULL, "DNS", 0, @@ -4315,6 +4350,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test failure for more than one SessionGroup argument config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123 " "SessionGroup=321"); @@ -4323,7 +4359,8 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(ret, OP_EQ, -1); // Test success with a sessiongroup options - config_free_lines(config_port_invalid); config_port_invalid = NULL; + config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 SessionGroup=1111122"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4335,6 +4372,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with a zero unix domain socket, and doesnt add it to out config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "0"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4344,6 +4382,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with a one unix domain socket, and doesnt add it to out config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "something"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4356,6 +4395,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with a port of auto - it uses the default address config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "auto"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4369,6 +4409,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with parsing both an address and an auto port config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "127.0.0.122:auto"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4389,6 +4430,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test success with parsing both an address and a real port config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "127.0.0.123:656"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, @@ -4401,7 +4443,8 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_assert(tor_addr_eq(&port_cfg->addr, &addr)) // Test failure if we can't parse anything at all - config_free_lines(config_port_valid); config_port_valid = NULL; + config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "something wrong"); ret = parse_port_config(slout, config_port_invalid, NULL, "DNS", 0, @@ -4410,6 +4453,7 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test failure if we find both an address, a port and an auto config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "127.0.1.0:123:auto"); ret = parse_port_config(slout, config_port_invalid, NULL, "DNS", 0, @@ -4418,7 +4462,8 @@ test_config_parse_port_config__ports__ports_given(void *data) // Test that default to group writeable default sets group writeable for // domain socket - config_free_lines(config_port_invalid); config_port_invalid = NULL; + config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "unix:/tmp/somewhere"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", @@ -4434,6 +4479,8 @@ test_config_parse_port_config__ports__ports_given(void *data) #endif done: + if (slout) + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_free(slout); config_free_lines(config_port_invalid); config_port_invalid = NULL; config_free_lines(config_port_valid); config_port_valid = NULL; @@ -4464,6 +4511,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test success with NoListen option config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "127.0.0.124:656 NoListen"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, NULL, 0, @@ -4476,6 +4524,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test failure with both NoAdvertise and NoListen option config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "127.0.0.124:656 NoListen " "NoAdvertise"); @@ -4485,6 +4534,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test success with IPv4Only config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "127.0.0.124:656 IPv4Only"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, NULL, 0, @@ -4497,6 +4547,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test success with IPv6Only config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "[::1]:656 IPv6Only"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, NULL, 0, @@ -4509,6 +4560,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test failure with both IPv4Only and IPv6Only config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "127.0.0.124:656 IPv6Only " "IPv4Only"); @@ -4518,6 +4570,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test success with invalid parameter config_free_lines(config_port_valid); config_port_valid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "127.0.0.124:656 unknown"); ret = parse_port_config(slout, config_port_valid, NULL, "DNS", 0, NULL, 0, @@ -4527,6 +4580,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test failure when asked to bind only to ipv6 but gets an ipv4 address config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "127.0.0.124:656 IPv6Only"); @@ -4536,6 +4590,7 @@ test_config_parse_port_config__ports__server_options(void *data) // Test failure when asked to bind only to ipv4 but gets an ipv6 address config_free_lines(config_port_invalid); config_port_invalid = NULL; + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "[::1]:656 IPv4Only"); ret = parse_port_config(slout, config_port_invalid, NULL, "DNS", 0, NULL, @@ -4543,6 +4598,8 @@ test_config_parse_port_config__ports__server_options(void *data) tt_int_op(ret, OP_EQ, -1); done: + if (slout) + SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_free(slout); config_free_lines(config_port_invalid); config_port_invalid = NULL; config_free_lines(config_port_valid); config_port_valid = NULL; diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 671ae7d7b2..c6684e285e 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -1090,7 +1090,7 @@ test_crypto_digests(void *arg) { crypto_pk_t *k = NULL; ssize_t r; - digests_t pkey_digests; + common_digests_t pkey_digests; char digest[DIGEST_LEN]; (void)arg; @@ -1104,7 +1104,7 @@ test_crypto_digests(void *arg) tt_mem_op(hex_str(digest, DIGEST_LEN),OP_EQ, AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN); - r = crypto_pk_get_all_digests(k, &pkey_digests); + r = crypto_pk_get_common_digests(k, &pkey_digests); tt_mem_op(hex_str(pkey_digests.d[DIGEST_SHA1], DIGEST_LEN),OP_EQ, AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN); diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 83a8b8ccc6..49719b9b36 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -497,7 +497,6 @@ test_dir_routerinfo_parsing(void *arg) #undef CHECK_FAIL #undef CHECK_OK done: - memarea_clear_freelist(); routerinfo_free(ri); } @@ -601,7 +600,6 @@ test_dir_extrainfo_parsing(void *arg) done: escaped(NULL); - memarea_clear_freelist(); extrainfo_free(ei); routerinfo_free(ri); digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_); @@ -1999,11 +1997,13 @@ test_a_networkstatus( tt_assert(con_md3); /* All three should have the same digest. */ - tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(digests_t)); - tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(digests_t)); + tt_mem_op(&con->digests,OP_EQ, &con2->digests, sizeof(common_digests_t)); + tt_mem_op(&con->digests,OP_EQ, &con3->digests, sizeof(common_digests_t)); - tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests, sizeof(digests_t)); - tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests, sizeof(digests_t)); + tt_mem_op(&con_md->digests,OP_EQ, &con_md2->digests, + sizeof(common_digests_t)); + tt_mem_op(&con_md->digests,OP_EQ, &con_md3->digests, + sizeof(common_digests_t)); /* Extract a detached signature from con3. */ detached_text1 = get_detached_sigs(con3, con_md3); @@ -2017,7 +2017,7 @@ test_a_networkstatus( tt_int_op(dsig1->fresh_until,OP_EQ, con3->fresh_until); tt_int_op(dsig1->valid_until,OP_EQ, con3->valid_until); { - digests_t *dsig_digests = strmap_get(dsig1->digests, "ns"); + common_digests_t *dsig_digests = strmap_get(dsig1->digests, "ns"); tt_assert(dsig_digests); tt_mem_op(dsig_digests->d[DIGEST_SHA1], OP_EQ, con3->digests.d[DIGEST_SHA1], DIGEST_LEN); diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index c81ed7ba89..46d76734e0 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -1764,7 +1764,7 @@ static void status_vote_current_consensus_ns_test(char **header, char **body, size_t *body_len) { - digests_t digests; + common_digests_t digests; dir_connection_t *conn = NULL; #define NETWORK_STATUS "some network status string" diff --git a/src/test/test_options.c b/src/test/test_options.c index b2be8a9c65..68e8f91128 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -158,7 +158,6 @@ test_options_validate_impl(const char *configuration, } done: - memarea_clear_freelist(); escaped(NULL); policies_free_all(); config_free_lines(cl); @@ -211,7 +210,7 @@ test_have_enough_mem_for_dircache(void *arg) { (void)arg; or_options_t *opt=NULL; - or_options_t *dflt; + or_options_t *dflt=NULL; config_line_t *cl=NULL; char *msg=NULL;; int r; @@ -293,7 +292,7 @@ test_have_enough_mem_for_dircache(void *arg) done: if (msg) tor_free(msg); - tor_free(dflt); + or_options_free(dflt); or_options_free(opt); config_free_lines(cl); return; @@ -1949,7 +1948,6 @@ test_options_validate__use_bridges(void *ignored) done: NS_UNMOCK(geoip_get_country); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2187,7 +2185,6 @@ test_options_validate__publish_server_descriptor(void *ignored) done: teardown_capture_of_logs(previous_log); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2263,7 +2260,6 @@ test_options_validate__testing(void *ignored) done: escaped(NULL); // This will free the leaking memory from the previous escaped - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2311,7 +2307,6 @@ test_options_validate__hidserv(void *ignored) done: teardown_capture_of_logs(previous_log); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2336,7 +2331,6 @@ test_options_validate__predicted_ports(void *ignored) done: teardown_capture_of_logs(previous_log); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2539,7 +2533,6 @@ test_options_validate__bandwidth(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2627,7 +2620,6 @@ test_options_validate__circuits(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -2661,7 +2653,6 @@ test_options_validate__port_forwarding(void *ignored) done: free_options_test_data(tdata); - memarea_clear_freelist(); policies_free_all(); tor_free(msg); } @@ -2691,7 +2682,6 @@ test_options_validate__tor2web(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -2758,7 +2748,6 @@ test_options_validate__rend(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -2878,7 +2867,6 @@ test_options_validate__accounting(void *ignored) done: teardown_capture_of_logs(previous_log); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -3210,7 +3198,6 @@ test_options_validate__proxy(void *ignored) done: teardown_capture_of_logs(previous_log); free_options_test_data(tdata); - memarea_clear_freelist(); policies_free_all(); // sandbox_free_getaddrinfo_cache(); tor_free(msg); @@ -3438,7 +3425,6 @@ test_options_validate__control(void *ignored) done: teardown_capture_of_logs(previous_log); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -3511,7 +3497,6 @@ test_options_validate__families(void *ignored) done: teardown_capture_of_logs(previous_log); - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -3536,7 +3521,6 @@ test_options_validate__addr_policies(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -3623,7 +3607,6 @@ test_options_validate__dir_auth(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -3749,7 +3732,6 @@ test_options_validate__transport(void *ignored) done: escaped(NULL); // This will free the leaking memory from the previous escaped - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -3833,7 +3815,6 @@ test_options_validate__constrained_sockets(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -4053,7 +4034,6 @@ test_options_validate__v3_auth(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -4088,7 +4068,6 @@ test_options_validate__virtual_addr(void *ignored) done: escaped(NULL); // This will free the leaking memory from the previous escaped - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); @@ -4130,7 +4109,6 @@ test_options_validate__exits(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -4299,7 +4277,6 @@ test_options_validate__testing_options(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); teardown_capture_of_logs(previous_log); free_options_test_data(tdata); @@ -4353,7 +4330,6 @@ test_options_validate__accel(void *ignored) tor_free(msg); done: - memarea_clear_freelist(); policies_free_all(); free_options_test_data(tdata); tor_free(msg); diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 3688909acb..84a7081588 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -1374,6 +1374,51 @@ test_policies_fascist_firewall_allows_address(void *arg) #define TEST_IPV6_OR_PORT 61234 #define TEST_IPV6_DIR_PORT 62345 +/* Check that fascist_firewall_choose_address_rs() returns the expected + * results. */ +#define CHECK_CHOSEN_ADDR_RS(fake_rs, fw_connection, pref_only, expect_rv, \ + expect_ap) \ + STMT_BEGIN \ + tor_addr_port_t chosen_rs_ap; \ + tor_addr_make_null(&chosen_rs_ap.addr, AF_INET); \ + chosen_rs_ap.port = 0; \ + tt_int_op(fascist_firewall_choose_address_rs(&(fake_rs), \ + (fw_connection), \ + (pref_only), \ + &chosen_rs_ap), \ + OP_EQ, (expect_rv)); \ + tt_assert(tor_addr_eq(&(expect_ap).addr, &chosen_rs_ap.addr)); \ + tt_int_op((expect_ap).port, OP_EQ, chosen_rs_ap.port); \ + STMT_END + +/* Check that fascist_firewall_choose_address_node() returns the expected + * results. */ +#define CHECK_CHOSEN_ADDR_NODE(fake_node, fw_connection, pref_only, \ + expect_rv, expect_ap) \ + STMT_BEGIN \ + tor_addr_port_t chosen_node_ap; \ + tor_addr_make_null(&chosen_node_ap.addr, AF_INET); \ + chosen_node_ap.port = 0; \ + tt_int_op(fascist_firewall_choose_address_node(&(fake_node), \ + (fw_connection), \ + (pref_only), \ + &chosen_node_ap), \ + OP_EQ, (expect_rv)); \ + tt_assert(tor_addr_eq(&(expect_ap).addr, &chosen_node_ap.addr)); \ + tt_int_op((expect_ap).port, OP_EQ, chosen_node_ap.port); \ + STMT_END + +/* Check that fascist_firewall_choose_address_rs and + * fascist_firewall_choose_address_node() both return the expected results. */ +#define CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, fw_connection, pref_only, \ + expect_rv, expect_ap) \ + STMT_BEGIN \ + CHECK_CHOSEN_ADDR_RS(fake_rs, fw_connection, pref_only, expect_rv, \ + expect_ap); \ + CHECK_CHOSEN_ADDR_NODE(fake_node, fw_connection, pref_only, expect_rv, \ + expect_ap); \ + STMT_END + /** Run unit tests for fascist_firewall_choose_address */ static void test_policies_fascist_firewall_choose_address(void *arg) @@ -1402,91 +1447,196 @@ test_policies_fascist_firewall_choose_address(void *arg) tor_addr_make_null(&n_ipv6_ap.addr, AF_INET6); n_ipv6_ap.port = 0; - /* Choose an address with IPv4 and IPv6 on */ + /* Sanity check fascist_firewall_choose_address with IPv4 and IPv6 on */ memset(&mock_options, 0, sizeof(or_options_t)); mock_options.ClientUseIPv4 = 1; mock_options.ClientUseIPv6 = 1; mock_options.UseBridges = 0; - /* Preferring IPv4 */ - mock_options.ClientPreferIPv6ORPort = 0; - mock_options.ClientPreferIPv6DirPort = 0; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) + /* Prefer IPv4 */ + tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 1, + FIREWALL_OR_CONNECTION, 0, 0) == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) + tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 1, + FIREWALL_OR_CONNECTION, 1, 0) == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) + tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 1, + FIREWALL_DIR_CONNECTION, 0, 0) == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) + tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 1, + FIREWALL_DIR_CONNECTION, 1, 0) == &ipv4_dir_ap); - /* Auto (Preferring IPv4) */ - mock_options.ClientPreferIPv6ORPort = -1; - mock_options.ClientPreferIPv6DirPort = -1; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv4_or_ap); + /* Prefer IPv6 */ tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv4_dir_ap); - - /* Preferring IPv6 */ - mock_options.ClientPreferIPv6ORPort = 1; - mock_options.ClientPreferIPv6DirPort = 1; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) + FIREWALL_OR_CONNECTION, 0, 1) == &ipv6_or_ap); tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) + FIREWALL_OR_CONNECTION, 1, 1) == &ipv6_or_ap); tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) + FIREWALL_DIR_CONNECTION, 0, 1) == &ipv6_dir_ap); tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) + FIREWALL_DIR_CONNECTION, 1, 1) == &ipv6_dir_ap); - /* Preferring IPv4 OR / IPv6 Dir */ - mock_options.ClientPreferIPv6ORPort = 0; - mock_options.ClientPreferIPv6DirPort = 1; + /* Unusual inputs */ + + /* null preferred OR addresses */ + tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &n_ipv6_ap, 0, + FIREWALL_OR_CONNECTION, 0, 1) + == &ipv4_or_ap); + tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &ipv6_or_ap, 1, + FIREWALL_OR_CONNECTION, 0, 0) + == &ipv6_or_ap); + + /* null both OR addresses */ + tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &n_ipv6_ap, 0, + FIREWALL_OR_CONNECTION, 0, 1) + == NULL); + tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &n_ipv6_ap, 1, + FIREWALL_OR_CONNECTION, 0, 0) + == NULL); + + /* null preferred Dir addresses */ + tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &n_ipv6_ap, 0, + FIREWALL_DIR_CONNECTION, 0, 1) + == &ipv4_dir_ap); + tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &ipv6_dir_ap, 1, + FIREWALL_DIR_CONNECTION, 0, 0) + == &ipv6_dir_ap); + + /* null both Dir addresses */ + tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &n_ipv6_ap, 0, + FIREWALL_DIR_CONNECTION, 0, 1) + == NULL); + tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &n_ipv6_ap, 1, + FIREWALL_DIR_CONNECTION, 0, 0) + == NULL); + + /* Prefer IPv4 but want IPv6 (contradictory) */ tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) + FIREWALL_OR_CONNECTION, 0, 0) == &ipv4_or_ap); tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) + FIREWALL_OR_CONNECTION, 1, 0) == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv6_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv6_dir_ap); + + /* Prefer IPv6 but want IPv4 (contradictory) */ + tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 1, + FIREWALL_OR_CONNECTION, 0, 1) + == &ipv6_or_ap); + tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 1, + FIREWALL_OR_CONNECTION, 1, 1) + == &ipv6_or_ap); + + /* Make a fake rs. There will be no corresponding node. + * This is what happens when there's no consensus and we're bootstrapping + * from authorities / fallbacks. */ + routerstatus_t fake_rs; + memset(&fake_rs, 0, sizeof(routerstatus_t)); + /* In a routerstatus, the OR and Dir addresses are the same */ + fake_rs.addr = tor_addr_to_ipv4h(&ipv4_or_ap.addr); + fake_rs.or_port = ipv4_or_ap.port; + fake_rs.dir_port = ipv4_dir_ap.port; + + tor_addr_copy(&fake_rs.ipv6_addr, &ipv6_or_ap.addr); + fake_rs.ipv6_orport = ipv6_or_ap.port; + /* In a routerstatus, the IPv4 and IPv6 DirPorts are the same.*/ + ipv6_dir_ap.port = TEST_IPV4_DIR_PORT; + + /* Make a fake node. Even though it contains the fake_rs, a lookup won't + * find the node from the rs, because they're not in the hash table. */ + node_t fake_node; + memset(&fake_node, 0, sizeof(node_t)); + fake_node.rs = &fake_rs; + + /* Choose an address with IPv4 and IPv6 on */ + memset(&mock_options, 0, sizeof(or_options_t)); + mock_options.ClientUseIPv4 = 1; + mock_options.ClientUseIPv6 = 1; + mock_options.UseBridges = 0; + + /* Preferring IPv4 */ + mock_options.ClientPreferIPv6ORPort = 0; + mock_options.ClientPreferIPv6DirPort = 0; + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); + + /* Auto (Preferring IPv4) */ + mock_options.ClientPreferIPv6ORPort = -1; + mock_options.ClientPreferIPv6DirPort = -1; + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); + + /* Preferring IPv6 */ + mock_options.ClientPreferIPv6ORPort = 1; + mock_options.ClientPreferIPv6DirPort = 1; + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv6_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv6_dir_ap); + + /* Preferring IPv4 OR / IPv6 Dir */ + mock_options.ClientPreferIPv6ORPort = 0; + mock_options.ClientPreferIPv6DirPort = 1; + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv6_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv6_dir_ap); /* Preferring IPv6 OR / IPv4 Dir */ mock_options.ClientPreferIPv6ORPort = 1; mock_options.ClientPreferIPv6DirPort = 0; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv4_dir_ap); + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); /* Choose an address with UseBridges on */ memset(&mock_options, 0, sizeof(or_options_t)); @@ -1497,157 +1647,175 @@ test_policies_fascist_firewall_choose_address(void *arg) /* Preferring IPv4 */ mock_options.ClientPreferIPv6ORPort = 0; mock_options.ClientPreferIPv6DirPort = 0; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv4_dir_ap); + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); /* Auto: - * - bridge clients prefer the configured bridge OR address, - * - other clients prefer IPv4 OR by default, - * - all clients prefer IPv4 Dir by default. + * - bridge clients prefer the configured bridge OR address from the node, + * (the configured address family sets node.ipv6_preferred) + * - other clients prefer IPv4 OR by default (see above), + * - all clients, including bridge clients, prefer IPv4 Dir by default. */ mock_options.ClientPreferIPv6ORPort = -1; mock_options.ClientPreferIPv6DirPort = -1; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv4_dir_ap); + + /* Simulate the initialisation of fake_node.ipv6_preferred with a bridge + * configured with an IPv4 address */ + fake_node.ipv6_preferred = 0; + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 0, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 1, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); + + /* Simulate the initialisation of fake_node.ipv6_preferred with a bridge + * configured with an IPv6 address */ + fake_node.ipv6_preferred = 1; + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 0, 1, ipv6_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 1, 1, ipv6_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); + + /* When a rs has no node, it defaults to IPv4 under auto. */ + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_OR_CONNECTION, 0, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_OR_CONNECTION, 1, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_DIR_CONNECTION, 0, 1, ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_DIR_CONNECTION, 1, 1, ipv4_dir_ap); /* Preferring IPv6 */ mock_options.ClientPreferIPv6ORPort = 1; mock_options.ClientPreferIPv6DirPort = 1; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv6_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv6_dir_ap); + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv6_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv6_dir_ap); /* In the default configuration (Auto / IPv6 off), bridge clients should - * still use IPv6, and only prefer it for bridges configured with an IPv6 - * address, regardless of ClientUseIPv6. */ + * use both IPv4 and IPv6, but only prefer IPv6 for bridges configured with + * an IPv6 address, regardless of ClientUseIPv6. (See above.) */ mock_options.ClientUseIPv6 = 0; mock_options.ClientPreferIPv6ORPort = -1; mock_options.ClientPreferIPv6DirPort = -1; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv4_dir_ap); + /* Simulate the initialisation of fake_node.ipv6_preferred with a bridge + * configured with an IPv4 address */ + fake_node.ipv6_preferred = 0; + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 0, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 1, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); + + /* Simulate the initialisation of fake_node.ipv6_preferred with a bridge + * configured with an IPv6 address */ + fake_node.ipv6_preferred = 1; + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 0, 1, ipv6_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_OR_CONNECTION, 1, 1, ipv6_or_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_NODE(fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); + + /* When a rs has no node, it defaults to IPv4 under auto. */ + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_OR_CONNECTION, 0, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_OR_CONNECTION, 1, 1, ipv4_or_ap); + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_DIR_CONNECTION, 0, 1, ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RS(fake_rs, FIREWALL_DIR_CONNECTION, 1, 1, ipv4_dir_ap); /* Choose an address with IPv4 on */ memset(&mock_options, 0, sizeof(or_options_t)); mock_options.ClientUseIPv4 = 1; mock_options.ClientUseIPv6 = 0; - mock_options.UseBridges = 0; - - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv4_dir_ap); + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); /* Choose an address with IPv6 on */ memset(&mock_options, 0, sizeof(or_options_t)); mock_options.ClientUseIPv4 = 0; mock_options.ClientUseIPv6 = 1; - mock_options.UseBridges = 0; - - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv6_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv6_dir_ap); + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv6_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv6_dir_ap); /* Choose an address with ClientUseIPv4 0. * This means "use IPv6" regardless of the other settings. */ memset(&mock_options, 0, sizeof(or_options_t)); mock_options.ClientUseIPv4 = 0; mock_options.ClientUseIPv6 = 0; - mock_options.UseBridges = 0; - - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 1) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv6_dir_ap); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 1) - == &ipv6_dir_ap); - - /* Choose from unusual inputs */ + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); + + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv6_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv6_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv6_dir_ap); + + /* Choose an address with ORPort_set 1 (server mode). + * This means "use IPv4" regardless of the other settings. */ memset(&mock_options, 0, sizeof(or_options_t)); - mock_options.ClientUseIPv4 = 1; + mock_options.ORPort_set = 1; + mock_options.ClientUseIPv4 = 0; mock_options.ClientUseIPv6 = 1; - mock_options.UseBridges = 1; + mock_options.ClientPreferIPv6ORPort = 1; + mock_options.ClientPreferIPv6DirPort = 1; - tt_assert(fascist_firewall_choose_address(&ipv4_or_ap, &n_ipv6_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv4_or_ap); - tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &ipv6_or_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == &ipv6_or_ap); - tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &n_ipv6_ap, 0, - FIREWALL_OR_CONNECTION, 0) - == NULL); + /* Simulate the initialisation of fake_node.ipv6_preferred */ + fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport( + &mock_options); - tt_assert(fascist_firewall_choose_address(&ipv4_dir_ap, &n_ipv6_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv4_dir_ap); - tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &ipv6_dir_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == &ipv6_dir_ap); - tt_assert(fascist_firewall_choose_address(&n_ipv4_ap, &n_ipv6_ap, 0, - FIREWALL_DIR_CONNECTION, 0) - == NULL); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1, + ipv4_or_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 0, 1, + ipv4_dir_ap); + CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1, + ipv4_dir_ap); done: UNMOCK(get_options); @@ -1660,6 +1828,10 @@ test_policies_fascist_firewall_choose_address(void *arg) #undef TEST_IPV6_OR_PORT #undef TEST_IPV6_DIR_PORT +#undef CHECK_CHOSEN_ADDR_RS +#undef CHECK_CHOSEN_ADDR_NODE +#undef CHECK_CHOSEN_ADDR_RN + struct testcase_t policy_tests[] = { { "router_dump_exit_policy_to_string", test_dump_exit_policy_to_string, 0, NULL, NULL }, diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c index 010dfd6dca..8b37cc025a 100644 --- a/src/test/test_routerlist.c +++ b/src/test/test_routerlist.c @@ -30,7 +30,7 @@ extern const char AUTHORITY_SIGNKEY_2[]; extern const char AUTHORITY_CERT_3[]; extern const char AUTHORITY_SIGNKEY_3[]; -void construct_consensus(const char **consensus_text_md); +void construct_consensus(char **consensus_text_md); /* 4 digests + 3 sep + pre + post + NULL */ static char output[4*BASE64_DIGEST256_LEN+3+2+2+1]; @@ -120,7 +120,7 @@ test_routerlist_launch_descriptor_downloads(void *arg) } void -construct_consensus(const char **consensus_text_md) +construct_consensus(char **consensus_text_md) { networkstatus_t *vote = NULL; networkstatus_t *v1 = NULL, *v2 = NULL, *v3 = NULL; @@ -145,7 +145,6 @@ construct_consensus(const char **consensus_text_md) tt_int_op(n_vrs, ==, 4); tt_int_op(smartlist_len(v1->routerstatus_list), ==, 4); - dir_common_construct_vote_2(&vote, cert2, sign_skey_2, &dir_common_gen_routerstatus_for_v3ns, &v2, &n_vrs, now, 1); @@ -181,6 +180,14 @@ construct_consensus(const char **consensus_text_md) networkstatus_vote_free(v1); networkstatus_vote_free(v2); networkstatus_vote_free(v3); + smartlist_free(votes); + authority_cert_free(cert1); + authority_cert_free(cert2); + authority_cert_free(cert3); + crypto_pk_free(sign_skey_1); + crypto_pk_free(sign_skey_2); + crypto_pk_free(sign_skey_3); + crypto_pk_free(sign_skey_leg); } static void @@ -189,7 +196,7 @@ test_router_pick_directory_server_impl(void *arg) (void)arg; networkstatus_t *con_md = NULL; - const char *consensus_text_md = NULL; + char *consensus_text_md = NULL; int flags = PDS_IGNORE_FASCISTFIREWALL|PDS_RETRY_IF_NO_SERVERS; or_options_t *options = get_options_mutable(); const routerstatus_t *rs = NULL; @@ -364,6 +371,8 @@ test_router_pick_directory_server_impl(void *arg) if (options->ReachableORAddresses || options->ReachableDirAddresses) policies_free_all(); + tor_free(consensus_text_md); + networkstatus_vote_free(con_md); } connection_t *mocked_connection = NULL; diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c index 138485c971..28847d4611 100644 --- a/src/test/test_tortls.c +++ b/src/test/test_tortls.c @@ -539,10 +539,10 @@ test_tortls_x509_cert_get_id_digests(void *ignored) { (void)ignored; tor_x509_cert_t *cert; - digests_t *d; - const digests_t *res; + common_digests_t *d; + const common_digests_t *res; cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); - d = tor_malloc_zero(sizeof(digests_t)); + d = tor_malloc_zero(sizeof(common_digests_t)); d->d[0][0] = 42; res = tor_x509_cert_get_id_digests(cert); diff --git a/src/test/test_util.c b/src/test/test_util.c index 37f7d938ea..0cec0c4893 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -4364,7 +4364,8 @@ test_util_socket(void *arg) (void)arg; fd1 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 0, 0); - if (SOCK_ERR_IS_EPROTO(fd1)) { + int err = tor_socket_errno(fd1); + if (fd1 < 0 && err == SOCK_ERRNO(EPROTONOSUPPORT)) { /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */ goto done; } |