commit 44ad73457303ed0bf80f6c4c645a62e03b42149b Merge: 7206d78 59f9097 Author: Nick Mathewson nickm@torproject.org Date: Wed May 11 16:23:42 2011 -0400
Merge remote-tracking branch 'public/3122_memcmp_squashed' into bug3122_memcmp_022
Conflicts throughout. All resolved in favor of taking HEAD and adding tor_mem* or fast_mem* ops as appropriate.
src/common/Makefile.am src/or/circuitbuild.c src/or/directory.c src/or/dirserv.c src/or/dirvote.c src/or/networkstatus.c src/or/rendclient.c src/or/rendservice.c src/or/router.c src/or/routerlist.c src/or/routerparse.c src/or/test.c
changes/bug3122_memcmp | 7 +++ configure.in | 18 ++++++ src/common/Makefile.am | 4 +- src/common/address.c | 2 +- src/common/compat.c | 4 +- src/common/container.c | 8 ++-- src/common/container.h | 4 +- src/common/crypto.c | 2 +- src/common/di_ops.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++ src/common/di_ops.h | 30 ++++++++++ src/common/torgzip.c | 2 +- src/common/util.c | 21 +++++--- src/common/util.h | 5 +- src/or/circuitbuild.c | 12 ++-- src/or/circuitlist.c | 10 ++-- src/or/circuituse.c | 2 +- src/or/connection_edge.c | 4 +- src/or/connection_or.c | 8 ++-- src/or/control.c | 14 +++--- src/or/directory.c | 10 ++-- src/or/dirserv.c | 8 ++-- src/or/dirvote.c | 36 ++++++------ src/or/eventdns.c | 2 +- src/or/networkstatus.c | 38 +++++++------- src/or/onion.c | 4 +- src/or/relay.c | 2 +- src/or/rendclient.c | 6 +- src/or/rendcommon.c | 8 ++-- src/or/rendmid.c | 2 +- src/or/rendservice.c | 16 +++--- src/or/rephist.c | 4 +- src/or/router.c | 6 +- src/or/routerlist.c | 60 ++++++++++---------- src/or/routerparse.c | 27 +++++----- 34 files changed, 358 insertions(+), 161 deletions(-)
diff --cc src/common/Makefile.am index b1e03cd,db94a98..2d009bd --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@@ -12,21 -10,7 +12,21 @@@ libor_extra_source endif
libor_a_SOURCES = address.c log.c util.c compat.c container.c mempool.c \ - memarea.c util_codedigest.c $(libor_extra_source) - memarea.c di_ops.c $(libor_extra_source) ++ memarea.c di_ops.c util_codedigest.c $(libor_extra_source) libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c +libor_event_a_SOURCES = compat_libevent.c + - noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc compat_libevent.h tortls_states.h ++noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc compat_libevent.h tortls_states.h di_ops.h + +common_sha1.i: $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) + if test "@SHA1SUM@" != none; then \ + @SHA1SUM@ $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) | @SED@ -n 's/^(.*)$$/"\1\n"/p' > common_sha1.i; \ + elif test "@OPENSSL@" != none; then \ + @OPENSSL@ sha1 $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) | @SED@ -n 's/SHA1((.*))= (.*)/"\2 \1\n"/p' > common_sha1.i; \ + else \ + rm common_sha1.i; \ + touch common_sha1.i; \ + fi
-noinst_HEADERS = address.h log.h crypto.h test.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h di_ops.h ciphers.inc +util_codedigest.o: common_sha1.i +crypto.o: sha256.c diff --cc src/common/util.c index 38c0ad0,879a0e4..86f4141 --- a/src/common/util.c +++ b/src/common/util.c @@@ -739,16 -662,12 +741,19 @@@ tor_mem_is_zero(const char *mem, size_ int tor_digest_is_zero(const char *digest) { - return tor_mem_is_zero(digest, DIGEST_LEN); + static const uint8_t ZERO_DIGEST[] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 + }; + return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN); }
+/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */ +int +tor_digest256_is_zero(const char *digest) +{ + return tor_mem_is_zero(digest, DIGEST256_LEN); +} + /* Helper: common code to check whether the result of a strtol or strtoul or * strtoll is correct. */ #define CHECK_STRTOX_RESULT() \ diff --cc src/or/circuitbuild.c index 2189e0e,208a9cb..a9986d3 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@@ -4504,10 -2997,11 +4504,10 @@@ get_configured_bridge_by_addr_port_dige SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { if (tor_digest_is_zero(bridge->identity) && - tor_addr_eq_ipv4h(&bridge->addr, ri->addr) && - bridge->port == ri->or_port) + !tor_addr_compare(&bridge->addr, addr, CMP_EXACT) && + bridge->port == port) return bridge; - if (!memcmp(bridge->identity, digest, DIGEST_LEN)) - if (tor_memeq(bridge->identity, ri->cache_info.identity_digest, - DIGEST_LEN)) ++ if (tor_memeq(bridge->identity, digest, DIGEST_LEN)) return bridge; } SMARTLIST_FOREACH_END(bridge); diff --cc src/or/directory.c index 68734e6,01f3375..309d997 --- a/src/or/directory.c +++ b/src/or/directory.c @@@ -2434,9 -2356,9 +2434,9 @@@ client_likes_consensus(networkstatus_t continue; };
- SMARTLIST_FOREACH(v->voters, networkstatus_voter_info_t *, vi, { - if (vi->signature && - fast_memeq(vi->identity_digest, want_digest, want_len)) { + SMARTLIST_FOREACH_BEGIN(v->voters, networkstatus_voter_info_t *, vi) { + if (smartlist_len(vi->sigs) && - !memcmp(vi->identity_digest, want_digest, want_len)) { ++ tor_memeq(vi->identity_digest, want_digest, want_len)) { have++; break; }; diff --cc src/or/dirserv.c index 860ac1f,e367cb1..1f4489a --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@@ -3152,23 -2841,15 +3152,23 @@@ dirserv_orconn_tls_done(const char *add tor_assert(address); tor_assert(digest_rcvd);
- SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, { + /* XXX023 Doing a loop like this is stupid. We should just look up the + * router by digest_rcvd, and see if address, orport, and as_advertised + * match up. -NM */ + SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) { if (!strcasecmp(address, ri->address) && or_port == ri->or_port && as_advertised && - !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) { + fast_memeq(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) { /* correct digest. mark this router reachable! */ if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) { - log_info(LD_DIRSERV, "Found router %s to be reachable. Yay.", - ri->nickname); - rep_hist_note_router_reachable(digest_rcvd, now); + tor_addr_t addr, *addrp=NULL; + log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.", + ri->nickname, address, ri->or_port ); + if (tor_addr_from_str(&addr, ri->address) != -1) + addrp = &addr; + else + log_warn(LD_BUG, "Couldn't parse IP address "%s"", ri->address); + rep_hist_note_router_reachable(digest_rcvd, addrp, or_port, now); ri->last_reachable = now; } } diff --cc src/or/dirvote.c index 750c649,9e763bd..a95cea4 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@@ -1765,11 -879,9 +1765,11 @@@ networkstatus_compute_consensus(smartli
/* Figure out the most popular opinion of what the most recent * routerinfo and its contents are. */ - rs = compute_routerstatus_consensus(matching_descs); + memset(microdesc_digest, 0, sizeof(microdesc_digest)); + rs = compute_routerstatus_consensus(matching_descs, consensus_method, + microdesc_digest); /* Copy bits of that into rs_out. */ - tor_assert(!memcmp(lowest_id, rs->status.identity_digest, DIGEST_LEN)); + tor_assert(fast_memeq(lowest_id, rs->status.identity_digest, DIGEST_LEN)); memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN); memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest, DIGEST_LEN); @@@ -2970,19 -1797,15 +2970,19 @@@ dirvote_add_vote(const char *vote_body goto err; }
+ /* Fetch any new router descriptors we just learned about */ + update_consensus_router_descriptor_downloads(time(NULL), 1, vote); + /* Now see whether we already have a vote from this authority. */ SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, { - if (! memcmp(v->vote->cert->cache_info.identity_digest, + if (fast_memeq(v->vote->cert->cache_info.identity_digest, vote->cert->cache_info.identity_digest, DIGEST_LEN)) { networkstatus_voter_info_t *vi_old = get_voter(v->vote); - if (!memcmp(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) { + if (fast_memeq(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) { /* Ah, it's the same vote. Not a problem. */ - log_info(LD_DIR, "Discarding a vote we already have."); + log_info(LD_DIR, "Discarding a vote we already have (from %s).", + vi->address); if (*status_out < 200) *status_out = 200; goto discard; @@@ -3491,12 -2229,12 +3491,12 @@@ dirvote_get_vote(const char *fp, int fl } else { if (pending_vote_list && include_pending) { SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv, - if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN)) - if (fast_memeq(pv->vote->networkstatus_digest, fp, DIGEST_LEN)) ++ if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN)) return pv->vote_body); } if (previous_vote_list && include_previous) { SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv, - if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN)) - if (fast_memeq(pv->vote->networkstatus_digest, fp, DIGEST_LEN)) ++ if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN)) return pv->vote_body); } } diff --cc src/or/networkstatus.c index a50d3ca,dcd8159..ff20566 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@@ -414,39 -341,35 +414,39 @@@ networkstatus_get_voter_by_id(networkst return NULL; }
-/** Check whether the signature on <b>voter</b> is correctly signed by - * the signing key of <b>cert</b>. Return -1 if <b>cert</b> doesn't match the +/** Check whether the signature <b>sig</b> is correctly signed with the + * signing key in <b>cert</b>. Return -1 if <b>cert</b> doesn't match the * signing key; otherwise set the good_signature or bad_signature flag on * <b>voter</b>, and return 0. */ -/* (private; exposed for testing.) */ int -networkstatus_check_voter_signature(networkstatus_t *consensus, - networkstatus_voter_info_t *voter, - authority_cert_t *cert) +networkstatus_check_document_signature(const networkstatus_t *consensus, + document_signature_t *sig, + const authority_cert_t *cert) { - char d[DIGEST_LEN]; + char key_digest[DIGEST_LEN]; + const int dlen = sig->alg == DIGEST_SHA1 ? DIGEST_LEN : DIGEST256_LEN; char *signed_digest; size_t signed_digest_len; - if (crypto_pk_get_digest(cert->signing_key, d)<0) + + if (crypto_pk_get_digest(cert->signing_key, key_digest)<0) return -1; - if (memcmp(sig->signing_key_digest, key_digest, DIGEST_LEN) || - memcmp(sig->identity_digest, cert->cache_info.identity_digest, - DIGEST_LEN)) - if (tor_memneq(voter->signing_key_digest, d, DIGEST_LEN)) ++ if (tor_memneq(sig->signing_key_digest, key_digest, DIGEST_LEN) || ++ tor_memneq(sig->identity_digest, cert->cache_info.identity_digest, ++ DIGEST_LEN)) return -1; + signed_digest_len = crypto_pk_keysize(cert->signing_key); signed_digest = tor_malloc(signed_digest_len); if (crypto_pk_public_checksig(cert->signing_key, signed_digest, signed_digest_len, - voter->signature, - voter->signature_len) != DIGEST_LEN || - tor_memneq(signed_digest, consensus->networkstatus_digest, DIGEST_LEN)) { + sig->signature, + sig->signature_len) < dlen || - memcmp(signed_digest, consensus->digests.d[sig->alg], dlen)) { ++ tor_memneq(signed_digest, consensus->digests.d[sig->alg], dlen)) { log_warn(LD_DIR, "Got a bad signature on a networkstatus vote"); - voter->bad_signature = 1; + sig->bad_signature = 1; } else { - voter->good_signature = 1; + sig->good_signature = 1; } tor_free(signed_digest); return 0; @@@ -1613,31 -1432,11 +1613,31 @@@ networkstatus_set_current_consensus(con goto done; }
- if (current_consensus && - tor_memeq(c->networkstatus_digest, current_consensus->networkstatus_digest, - DIGEST_LEN)) { + if (!strcmp(flavor, "ns")) { + consensus_fname = get_datadir_fname("cached-consensus"); + unverified_fname = get_datadir_fname("unverified-consensus"); + if (current_consensus) { + current_digests = ¤t_consensus->digests; + current_valid_after = current_consensus->valid_after; + } + } else { + cached_dir_t *cur; + char buf[128]; + tor_snprintf(buf, sizeof(buf), "cached-%s-consensus", flavor); + consensus_fname = get_datadir_fname(buf); + tor_snprintf(buf, sizeof(buf), "unverified-%s-consensus", flavor); + unverified_fname = get_datadir_fname(buf); + cur = dirserv_get_consensus(flavor); + if (cur) { + current_digests = &cur->digests; + current_valid_after = cur->published; + } + } + + if (current_digests && - !memcmp(&c->digests, current_digests, sizeof(c->digests))) { ++ tor_memeq(&c->digests, current_digests, sizeof(c->digests))) { /* We already have this one. That's a failure. */ - log_info(LD_DIR, "Got a consensus we already have"); + log_info(LD_DIR, "Got a %s consensus we already have", flavor); goto done; }
diff --cc src/or/rendclient.c index e4a6d09,7bda705..77e11c2 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@@ -154,27 -98,42 +154,27 @@@ rend_client_send_introduction(origin_ci }
/* first 20 bytes of payload are the hash of Bob's pk */ - if (entry->parsed->version == 0) { /* un-versioned descriptor */ - intro_key = entry->parsed->pk; - } else { /* versioned descriptor */ - intro_key = NULL; - SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *, - intro, { - if (tor_memeq(introcirc->build_state->chosen_exit->identity_digest, - intro->extend_info->identity_digest, DIGEST_LEN)) { - intro_key = intro->intro_key; - break; - } - }); - if (!intro_key) { - /** XXX This case probably means that the intro point vanished while - * we were building a circuit to it. In the future, we should find - * out how that happened and whether we should kill the circuits to - * removed intro points immediately. See task 1073. */ - int num_intro_points = smartlist_len(entry->parsed->intro_nodes); - if (rend_cache_lookup_entry(introcirc->rend_data->onion_address, - 0, &entry) > 0) { - log_info(LD_REND, "We have both a v0 and a v2 rend desc for this " - "service. The v2 desc doesn't contain the introduction " - "point (and key) to send an INTRODUCE1/2 cell to this " - "introduction point. Assuming the introduction point " - "is for v0 rend clients and using the service key " - "from the v0 desc instead. (This is probably a bug, " - "because we shouldn't even have both a v0 and a v2 " - "descriptor for the same service.)"); - /* See flyspray task 1024. */ - intro_key = entry->parsed->pk; - } else { - log_info(LD_REND, "Internal error: could not find intro key; we " - "only have a v2 rend desc with %d intro points.", - num_intro_points); - goto perm_err; - } + intro_key = NULL; + SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *, + intro, { - if (!memcmp(introcirc->build_state->chosen_exit->identity_digest, ++ if (tor_memeq(introcirc->build_state->chosen_exit->identity_digest, + intro->extend_info->identity_digest, DIGEST_LEN)) { + intro_key = intro->intro_key; + break; + } + }); + if (!intro_key) { + log_info(LD_REND, "Could not find intro key for %s at %s; we " + "have a v2 rend desc with %d intro points. " + "Trying a different intro point...", + safe_str_client(introcirc->rend_data->onion_address), + introcirc->build_state->chosen_exit->nickname, + smartlist_len(entry->parsed->intro_nodes)); + + if (rend_client_reextend_intro_circuit(introcirc)) { + goto perm_err; + } else { + return -1; } } if (crypto_pk_get_digest(intro_key, payload)<0) { diff --cc src/or/rendcommon.c index f8e7f9b,c83573b..da33fec --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@@ -1067,9 -1101,9 +1067,9 @@@ rend_cache_store(const char *desc, size rend_service_descriptor_free(parsed); return 0; } - if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) { + if (e && e->len == desc_len && tor_memeq(desc,e->desc,desc_len)) { log_info(LD_REND,"We already have this service descriptor %s.", - safe_str(query)); + safe_str_client(query)); e->received = time(NULL); rend_service_descriptor_free(parsed); return 0; diff --cc src/or/rendservice.c index cd8f9ea,d1cc7f4..35e8b90 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@@ -465,8 -506,9 +465,8 @@@ rend_config_services(or_options_t *opti int keep_it = 0; tor_assert(oc->rend_data); SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, { - if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest, + if (tor_memeq(ptr->pk_digest, oc->rend_data->rend_pk_digest, - DIGEST_LEN) && - ptr->descriptor_version == oc->rend_data->rend_desc_version) { + DIGEST_LEN)) { keep_it = 1; break; } @@@ -753,15 -797,17 +753,15 @@@ rend_service_load_keys(void return r; }
-/** Return the service whose public key has a digest of <b>digest</b> and - * which publishes the given descriptor <b>version</b>. Return NULL if no - * such service exists. +/** Return the service whose public key has a digest of <b>digest</b>, or + * NULL if no such service exists. */ static rend_service_t * -rend_service_get_by_pk_digest_and_version(const char* digest, - uint8_t version) +rend_service_get_by_pk_digest(const char* digest) { SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s, - if (!memcmp(s->pk_digest,digest,DIGEST_LEN)) - if (tor_memeq(s->pk_digest,digest,DIGEST_LEN) && - s->descriptor_version == version) return s); ++ if (tor_memeq(s->pk_digest,digest,DIGEST_LEN)) + return s); return NULL; }
@@@ -1555,9 -1593,10 +1555,9 @@@ find_intro_circuit(rend_intro_point_t * tor_assert(intro); while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, CIRCUIT_PURPOSE_S_INTRO))) { - if (!memcmp(circ->build_state->chosen_exit->identity_digest, + if (tor_memeq(circ->build_state->chosen_exit->identity_digest, intro->extend_info->identity_digest, DIGEST_LEN) && - circ->rend_data && - circ->rend_data->rend_desc_version == desc_version) { + circ->rend_data) { return circ; } } @@@ -1565,9 -1604,10 +1565,9 @@@ circ = NULL; while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) { - if (!memcmp(circ->build_state->chosen_exit->identity_digest, + if (tor_memeq(circ->build_state->chosen_exit->identity_digest, intro->extend_info->identity_digest, DIGEST_LEN) && - circ->rend_data && - circ->rend_data->rend_desc_version == desc_version) { + circ->rend_data) { return circ; } } diff --cc src/or/router.c index 65afd49,cc60041..a7148ea --- a/src/or/router.c +++ b/src/or/router.c @@@ -1260,8 -1119,7 +1260,8 @@@ router_my_exit_policy_is_reject_star(vo int router_digest_is_me(const char *digest) { - return identitykey && tor_memeq(identitykey_digest, digest, DIGEST_LEN); + return (server_identitykey && - !memcmp(server_identitykey_digest, digest, DIGEST_LEN)); ++ tor_memeq(server_identitykey_digest, digest, DIGEST_LEN)); }
/** Return true iff I'm a server and <b>digest</b> is equal to diff --cc src/or/routerlist.c index f567ccd,9f04620..b0909eb --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@@ -3328,15 -2999,16 +3328,15 @@@ router_add_to_routerlist(routerinfo_t * SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, { routerstatus_t *rs = - networkstatus_v2_find_entry(ns, router->cache_info.identity_digest); + networkstatus_v2_find_entry(ns, id_digest); - if (rs && !memcmp(rs->descriptor_digest, + if (rs && tor_memeq(rs->descriptor_digest, router->cache_info.signed_descriptor_digest, DIGEST_LEN)) rs->need_to_mirror = 0; }); if (consensus) { - routerstatus_t *rs = networkstatus_vote_find_entry(consensus, - router->cache_info.identity_digest); + routerstatus_t *rs = networkstatus_vote_find_entry(consensus, id_digest); - if (rs && !memcmp(rs->descriptor_digest, + if (rs && tor_memeq(rs->descriptor_digest, router->cache_info.signed_descriptor_digest, DIGEST_LEN)) { in_consensus = 1; diff --cc src/or/routerparse.c index d0138e6,7ff0e2c..3b669ad --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@@ -1095,7 -959,7 +1095,7 @@@ check_signature_token(const char *diges } // log_debug(LD_DIR,"Signed %s hash starts %s", doctype, // hex_str(signed_digest,4)); - if (memcmp(digest, signed_digest, digest_len)) { - if (tor_memneq(digest, signed_digest, DIGEST_LEN)) { ++ if (tor_memneq(digest, signed_digest, digest_len)) { log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype); tor_free(signed_digest); return -1; @@@ -2190,11 -2001,11 +2190,11 @@@ routerstatus_parse_entry_from_string(me }
/** Helper to sort a smartlist of pointers to routerstatus_t */ -static int -_compare_routerstatus_entries(const void **_a, const void **_b) +int +compare_routerstatus_entries(const void **_a, const void **_b) { const routerstatus_t *a = *_a, *b = *_b; - return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN); + return fast_memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN); }
/** Helper: used in call to _smartlist_uniq to clear out duplicate entries. */
tor-commits@lists.torproject.org