[tor-commits] [tor/release-0.2.4] Merge bug5595-v2-squashed into maint-0.2.4
arma at torproject.org
arma at torproject.org
Sat May 25 03:58:41 UTC 2013
commit aaa3a085db05c4d98b7c51b5ef16da166e7c7f0a
Merge: bae5dd6 54f41d6
Author: Andrea Shepard <andrea at torproject.org>
Date: Fri May 10 19:39:48 2013 -0700
Merge bug5595-v2-squashed into maint-0.2.4
changes/bug5595 | 8 +
src/or/Makefile.nmake | 1 +
src/or/directory.c | 73 +++++--
src/or/dirvote.c | 2 +-
src/or/fp_pair.c | 308 ++++++++++++++++++++++++++
src/or/fp_pair.h | 45 ++++
src/or/include.am | 2 +
src/or/router.c | 3 +-
src/or/routerlist.c | 516 ++++++++++++++++++++++++++++++++++++--------
src/or/routerlist.h | 18 +-
src/test/test_containers.c | 84 ++++++++
11 files changed, 949 insertions(+), 111 deletions(-)
diff --cc src/or/Makefile.nmake
index d67123a,146866e..3b627b1
--- a/src/or/Makefile.nmake
+++ b/src/or/Makefile.nmake
@@@ -1,74 -1,28 +1,75 @@@
all: tor.exe
-CFLAGS = /I ..\win32 /I ..\..\..\build-alpha\include /I ..\common
+CFLAGS = /I ..\win32 /I ..\..\..\build-alpha\include /I ..\common \
+ /I ..\ext
-LIBS = ..\..\..\build-alpha\lib\libevent.a \
- ..\..\..\build-alpha\lib\libcrypto.a \
- ..\..\..\build-alpha\lib\libssl.a \
- ..\..\..\build-alpha\lib\libz.a \
- ws2_32.lib advapi32.lib shell32.lib
+LIBS = ..\..\..\build-alpha\lib\libevent.lib \
+ ..\..\..\build-alpha\lib\libcrypto.lib \
+ ..\..\..\build-alpha\lib\libssl.lib \
+ ..\..\..\build-alpha\lib\libz.lib \
+ ws2_32.lib advapi32.lib shell32.lib \
+ crypt32.lib gdi32.lib user32.lib
-LIBTOR_OBJECTS = buffers.obj circuitbuild.obj circuitlist.obj circuituse.obj \
- command.obj config.obj connection.obj connection_edge.obj \
- connection_or.obj control.obj cpuworker.obj directory.obj \
- dirserv.obj dirvote.obj dns.obj dnsserv.obj fp_pair.obj geoip.obj \
- hibernate.obj main.obj microdesc.obj networkstatus.obj \
- nodelist.obj onion.obj policies.obj reasons.obj relay.obj \
- rendclient.obj rendcommon.obj rendmid.obj rendservice.obj \
- rephist.obj router.obj routerlist.obj routerparse.obj status.obj \
- config_codedigest.obj ntmain.obj
+LIBTOR_OBJECTS = \
+ addressmap.obj \
+ buffers.obj \
+ channel.obj \
+ channeltls.obj \
+ circuitbuild.obj \
+ circuitlist.obj \
+ circuitmux.obj \
+ circuitmux_ewma.obj \
+ circuitstats.obj \
+ circuituse.obj \
+ command.obj \
+ config.obj \
+ config_codedigest.obj \
+ confparse.obj \
+ connection.obj \
+ connection_edge.obj \
+ connection_or.obj \
+ control.obj \
+ cpuworker.obj \
+ directory.obj \
+ dirserv.obj \
+ dirvote.obj \
+ dns.obj \
+ dnsserv.obj \
++ fp_pair.obj \
+ entrynodes.obj \
+ geoip.obj \
+ hibernate.obj \
+ main.obj \
+ microdesc.obj \
+ networkstatus.obj \
+ nodelist.obj \
+ ntmain.obj \
+ onion.obj \
+ onion_fast.obj \
+ onion_ntor.obj \
+ onion_tap.obj \
+ policies.obj \
+ reasons.obj \
+ relay.obj \
+ rendclient.obj \
+ rendcommon.obj \
+ rendmid.obj \
+ rendservice.obj \
+ rephist.obj \
+ replaycache.obj \
+ router.obj \
+ routerlist.obj \
+ routerparse.obj \
+ routerset.obj \
+ statefile.obj \
+ status.obj \
+ transports.obj
libtor.lib: $(LIBTOR_OBJECTS)
- lib $(LIBTOR_OBJECTS) /out:libtor.lib
+ lib $(LIBTOR_OBJECTS) /out:$@
tor.exe: libtor.lib tor_main.obj
- $(CC) $(CFLAGS) $(LIBS) libtor.lib ..\common\*.lib tor_main.obj
+ $(CC) $(CFLAGS) $(LIBS) libtor.lib ..\common\*.lib tor_main.obj /Fe$@
clean:
del $(LIBTOR_OBJECTS) *.lib tor.exe
diff --cc src/or/directory.c
index 38a423c,f65ac87..b4381ac
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@@ -856,8 -803,10 +856,10 @@@ connection_dir_bridge_routerdesc_failed
static void
connection_dir_download_cert_failed(dir_connection_t *conn, int status)
{
+ const char *fp_pfx = "fp/";
+ const char *fpsk_pfx = "fp-sk/";
smartlist_t *failed;
- tor_assert(conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
+ tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
if (!conn->requested_resource)
return;
@@@ -1629,11 -1608,12 +1653,12 @@@ connection_dir_client_reached_eof(dir_c
compress_method_t compression;
int plausible;
int skewed=0;
- int allow_partial = (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
- conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
- conn->_base.purpose == DIR_PURPOSE_FETCH_MICRODESC);
+ int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
+ conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
+ conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
int was_compressed=0;
time_t now = time(NULL);
+ int src_code;
switch (connection_fetch_from_buf_http(TO_CONN(conn),
&headers, MAX_HEADERS_SIZE,
@@@ -1901,18 -1881,37 +1926,38 @@@
return -1;
}
log_info(LD_DIR,"Received authority certificates (size %d) from server "
- "'%s:%d'", (int)body_len, conn->_base.address, conn->_base.port);
+ "'%s:%d'", (int)body_len, conn->base_.address, conn->base_.port);
- if (trusted_dirs_load_certs_from_string(body, 0, 1)<0) {
- log_warn(LD_DIR, "Unable to parse fetched certificates");
- /* if we fetched more than one and only some failed, the successful
- * ones got flushed to disk so it's safe to call this on them */
- connection_dir_download_cert_failed(conn, status_code);
++
+ /*
+ * Tell trusted_dirs_load_certs_from_string() whether it was by fp
+ * or fp-sk pair.
+ */
+ src_code = -1;
+ if (!strcmpstart(conn->requested_resource, "fp/")) {
+ src_code = TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST;
+ } else if (!strcmpstart(conn->requested_resource, "fp-sk/")) {
+ src_code = TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST;
+ }
+
+ if (src_code != -1) {
+ if (trusted_dirs_load_certs_from_string(body, src_code, 1)<0) {
+ log_warn(LD_DIR, "Unable to parse fetched certificates");
+ /* if we fetched more than one and only some failed, the successful
+ * 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);
+ log_info(LD_DIR, "Successfully loaded certificates from fetch.");
+ }
} else {
- directory_info_has_arrived(now, 0);
- log_info(LD_DIR, "Successfully loaded certificates from fetch.");
+ log_warn(LD_DIR,
+ "Couldn't figure out what to do with fetched certificates for "
+ "unknown resource %s",
+ conn->requested_resource);
+ connection_dir_download_cert_failed(conn, status_code);
}
}
- if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
+ if (conn->base_.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
const char *msg;
int st;
log_info(LD_DIR,"Got votes (size %d) from server %s:%d",
diff --cc src/or/include.am
index d2be1fb,0000000..65dbeff
mode 100644,000000..100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@@ -1,193 -1,0 +1,195 @@@
+bin_PROGRAMS+= src/or/tor
+noinst_LIBRARIES+= src/or/libtor.a
+
+if BUILD_NT_SERVICES
+tor_platform_source=src/or/ntmain.c
+else
+tor_platform_source=
+endif
+
+EXTRA_DIST+= src/or/ntmain.c src/or/or_sha1.i src/or/Makefile.nmake
+
+if USE_EXTERNAL_EVDNS
+evdns_source=
+else
+evdns_source=src/ext/eventdns.c
+endif
+
+if CURVE25519_ENABLED
+onion_ntor_source=src/or/onion_ntor.c
+else
+onion_ntor_source=
+endif
+
+src_or_libtor_a_SOURCES = \
+ src/or/addressmap.c \
+ src/or/buffers.c \
+ src/or/channel.c \
+ src/or/channeltls.c \
+ src/or/circuitbuild.c \
+ src/or/circuitlist.c \
+ src/or/circuitmux.c \
+ src/or/circuitmux_ewma.c \
+ src/or/circuitstats.c \
+ src/or/circuituse.c \
+ src/or/command.c \
+ src/or/config.c \
+ src/or/confparse.c \
+ src/or/connection.c \
+ src/or/connection_edge.c \
+ src/or/connection_or.c \
+ src/or/control.c \
+ src/or/cpuworker.c \
+ src/or/directory.c \
+ src/or/dirserv.c \
+ src/or/dirvote.c \
+ src/or/dns.c \
+ src/or/dnsserv.c \
++ src/or/fp_pair.c \
+ src/or/geoip.c \
+ src/or/entrynodes.c \
+ src/or/hibernate.c \
+ src/or/main.c \
+ src/or/microdesc.c \
+ src/or/networkstatus.c \
+ src/or/nodelist.c \
+ src/or/onion.c \
+ src/or/onion_fast.c \
+ src/or/onion_tap.c \
+ src/or/transports.c \
+ src/or/policies.c \
+ src/or/reasons.c \
+ src/or/relay.c \
+ src/or/rendclient.c \
+ src/or/rendcommon.c \
+ src/or/rendmid.c \
+ src/or/rendservice.c \
+ src/or/rephist.c \
+ src/or/replaycache.c \
+ src/or/router.c \
+ src/or/routerlist.c \
+ src/or/routerparse.c \
+ src/or/routerset.c \
+ src/or/statefile.c \
+ src/or/status.c \
+ $(evdns_source) \
+ $(tor_platform_source) \
+ $(onion_ntor_source) \
+ src/or/config_codedigest.c
+
+#libtor_a_LIBADD = ../common/libor.a ../common/libor-crypto.a \
+# ../common/libor-event.a
+
+
+src_or_tor_SOURCES = src/or/tor_main.c
+AM_CPPFLAGS += -I$(srcdir)/src/or -Isrc/or
+
+src/or/tor_main.o: micro-revision.i
+
+AM_CPPFLAGS += -DSHARE_DATADIR="\"$(datadir)\"" \
+ -DLOCALSTATEDIR="\"$(localstatedir)\"" \
+ -DBINDIR="\"$(bindir)\""
+
+# -L flags need to go in LDFLAGS. -l flags need to go in LDADD.
+# This seems to matter nowhere but on windows, but I assure you that it
+# matters a lot there, and is quite hard to debug if you forget to do it.
+
+
+src_or_tor_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
+src_or_tor_LDADD = src/or/libtor.a src/common/libor.a \
+ src/common/libor-crypto.a $(LIBDONNA) \
+ src/common/libor-event.a \
+ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
+ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+
+ORHEADERS = \
+ src/or/addressmap.h \
+ src/or/buffers.h \
+ src/or/channel.h \
+ src/or/channeltls.h \
+ src/or/circuitbuild.h \
+ src/or/circuitlist.h \
+ src/or/circuitmux.h \
+ src/or/circuitmux_ewma.h \
+ src/or/circuitstats.h \
+ src/or/circuituse.h \
+ src/or/command.h \
+ src/or/config.h \
+ src/or/confparse.h \
+ src/or/connection.h \
+ src/or/connection_edge.h \
+ src/or/connection_or.h \
+ src/or/control.h \
+ src/or/cpuworker.h \
+ src/or/directory.h \
+ src/or/dirserv.h \
+ src/or/dirvote.h \
+ src/or/dns.h \
+ src/or/dnsserv.h \
+ src/or/eventdns_tor.h \
++ src/or/fp_pair.h \
+ src/or/geoip.h \
+ src/or/entrynodes.h \
+ src/or/hibernate.h \
+ src/or/main.h \
+ src/or/microdesc.h \
+ src/or/networkstatus.h \
+ src/or/nodelist.h \
+ src/or/ntmain.h \
+ src/or/onion.h \
+ src/or/onion_fast.h \
+ src/or/onion_ntor.h \
+ src/or/onion_tap.h \
+ src/or/or.h \
+ src/or/transports.h \
+ src/or/policies.h \
+ src/or/reasons.h \
+ src/or/relay.h \
+ src/or/rendclient.h \
+ src/or/rendcommon.h \
+ src/or/rendmid.h \
+ src/or/rendservice.h \
+ src/or/rephist.h \
+ src/or/replaycache.h \
+ src/or/router.h \
+ src/or/routerlist.h \
+ src/or/routerset.h \
+ src/or/routerparse.h \
+ src/or/statefile.h \
+ src/or/status.h
+
+noinst_HEADERS+= $(ORHEADERS) micro-revision.i
+
+src/or/config_codedigest.o: src/or/or_sha1.i
+
+micro-revision.i: FORCE
+ @rm -f micro-revision.tmp; \
+ if test -d "$(top_srcdir)/.git" && \
+ test -x "`which git 2>&1;true`"; then \
+ HASH="`cd "$(top_srcdir)" && git rev-parse --short=16 HEAD`"; \
+ echo \"$$HASH\" > micro-revision.tmp; \
+ fi; \
+ if test ! -f micro-revision.tmp ; then \
+ if test ! -f micro-revision.i ; then \
+ echo '""' > micro-revision.i; \
+ fi; \
+ elif test ! -f micro-revision.i || \
+ test x"`cat micro-revision.tmp`" != x"`cat micro-revision.i`"; then \
+ mv micro-revision.tmp micro-revision.i; \
+ fi; true
+
+src/or/or_sha1.i: $(src_or_tor_SOURCES) $(src_or_libtor_a_SOURCES) $(ORHEADERS)
+ $(AM_V_GEN)if test "@SHA1SUM@" != none; then \
+ (cd "$(srcdir)" && "@SHA1SUM@" $(src_or_tor_SOURCES) $(src_or_libtor_a_SOURCES) $(ORHEADERS) ) | \
+ "@SED@" -n 's/^\(.*\)$$/"\1\\n"/p' > src/or/or_sha1.i; \
+ elif test "@OPENSSL@" != none; then \
+ (cd "$(srcdir)" && "@OPENSSL@" sha1 $(src_or_tor_SOURCES) $(src_or_libtor_a_SOURCES) $(ORHEADERS)) | \
+ "@SED@" -n 's/SHA1(\(.*\))= \(.*\)/"\2 \1\\n"/p' > src/or/or_sha1.i; \
+ else \
+ rm src/or/or_sha1.i; \
+ touch src/or/or_sha1.i; \
+ fi
+
+CLEANFILES+= micro-revision.i src/or/micro-revision.i
+
+FORCE:
diff --cc src/or/routerlist.c
index 6ed168e,aa1660f..c2220f4
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@@ -20,7 -19,7 +20,8 @@@
#include "directory.h"
#include "dirserv.h"
#include "dirvote.h"
+#include "entrynodes.h"
+ #include "fp_pair.h"
#include "geoip.h"
#include "hibernate.h"
#include "main.h"
@@@ -41,10 -39,25 +42,28 @@@
/****************************************************************************/
+ DECLARE_TYPED_DIGESTMAP_FNS(sdmap_, digest_sd_map_t, signed_descriptor_t)
+ DECLARE_TYPED_DIGESTMAP_FNS(rimap_, digest_ri_map_t, routerinfo_t)
+ DECLARE_TYPED_DIGESTMAP_FNS(eimap_, digest_ei_map_t, extrainfo_t)
+ DECLARE_TYPED_DIGESTMAP_FNS(dsmap_, digest_ds_map_t, download_status_t)
+ #define SDMAP_FOREACH(map, keyvar, valvar) \
+ DIGESTMAP_FOREACH(sdmap_to_digestmap(map), keyvar, signed_descriptor_t *, \
+ valvar)
+ #define RIMAP_FOREACH(map, keyvar, valvar) \
+ DIGESTMAP_FOREACH(rimap_to_digestmap(map), keyvar, routerinfo_t *, valvar)
+ #define EIMAP_FOREACH(map, keyvar, valvar) \
+ DIGESTMAP_FOREACH(eimap_to_digestmap(map), keyvar, extrainfo_t *, valvar)
+ #define DSMAP_FOREACH(map, keyvar, valvar) \
+ DIGESTMAP_FOREACH(dsmap_to_digestmap(map), keyvar, download_status_t *, \
+ valvar)
+
+ /* Forward declaration for cert_list_t */
+ typedef struct cert_list_t cert_list_t;
+
/* static function prototypes */
+static int compute_weighted_bandwidths(const smartlist_t *sl,
+ bandwidth_weight_rule_t rule,
+ u64_dbl_t **bandwidths_out);
static const routerstatus_t *router_pick_directory_server_impl(
dirinfo_type_t auth, int flags);
static const routerstatus_t *router_pick_trusteddirserver_impl(
@@@ -190,17 -272,23 +280,23 @@@ already_have_cert(authority_cert_t *cer
}
/** Load a bunch of new key certificates from the string <b>contents</b>. If
- * <b>from_store</b> is true, the certificates are from the cache, and we
- * don't need to flush them to disk. If <b>flush</b> is true, we need
- * to flush any changed certificates to disk now. Return 0 on success, -1
- * if any certs fail to parse. */
+ * <b>source</b> is TRUSTED_DIRS_CERTS_SRC_FROM_STORE, the certificates are
+ * from the cache, and we don't need to flush them to disk. If we are a
+ * dirauth loading our own cert, source is TRUSTED_DIRS_CERTS_SRC_SELF.
+ * Otherwise, source is download type: TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST
+ * or TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST. If <b>flush</b> is true, we
+ * need to flush any changed certificates to disk now. Return 0 on success,
+ * -1 if any certs fail to parse.
+ */
+
int
- trusted_dirs_load_certs_from_string(const char *contents, int from_store,
+ trusted_dirs_load_certs_from_string(const char *contents, int source,
int flush)
{
- trusted_dir_server_t *ds;
+ dir_server_t *ds;
const char *s, *eos;
int failure_code = 0;
+ int from_store = (source == TRUSTED_DIRS_CERTS_SRC_FROM_STORE);
for (s = contents; *s; s = eos) {
authority_cert_t *cert = authority_cert_parse_from_string(s, &eos);
@@@ -504,10 -659,62 +666,63 @@@ authority_certs_fetch_missing(networkst
if (should_delay_dir_fetches(get_options()))
return;
- pending = digestmap_new();
- missing_digests = smartlist_new();
+ pending_cert = fp_pair_map_new();
+ pending_id = digestmap_new();
+ missing_cert_digests = smartlist_new();
+ missing_id_digests = smartlist_new();
+
+ /*
+ * First, we get the lists of already pending downloads so we don't
+ * duplicate effort.
+ */
+ list_pending_downloads(pending_id, DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
+ list_pending_fpsk_downloads(pending_cert);
- list_pending_downloads(pending, DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
+ /*
+ * Now, we download any trusted authority certs we don't have by
+ * identity digest only. This gets the latest cert for that authority.
+ */
- SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, ds) {
++ SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, dir_server_t *, ds) {
+ int found = 0;
+ if (!(ds->type & V3_DIRINFO))
+ continue;
- if (smartlist_digest_isin(missing_id_digests, ds->v3_identity_digest))
++ if (smartlist_contains_digest(missing_id_digests,
++ ds->v3_identity_digest))
+ continue;
+ cl = get_cert_list(ds->v3_identity_digest);
+ SMARTLIST_FOREACH_BEGIN(cl->certs, authority_cert_t *, cert) {
+ if (now < cert->expires) {
+ /* It's not expired, and we weren't looking for something to
+ * verify a consensus with. Call it done. */
+ download_status_reset(&(cl->dl_status_by_id));
+ /* No sense trying to download it specifically by signing key hash */
+ download_status_reset_by_sk_in_cl(cl, cert->signing_key_digest);
+ found = 1;
+ break;
+ }
+ } SMARTLIST_FOREACH_END(cert);
+ if (!found &&
+ download_status_is_ready(&(cl->dl_status_by_id), now,
+ MAX_CERT_DL_FAILURES) &&
+ !digestmap_get(pending_id, ds->v3_identity_digest)) {
+ log_info(LD_DIR,
+ "No current certificate known for authority %s "
+ "(ID digest %s); launching request.",
+ ds->nickname, hex_str(ds->v3_identity_digest, DIGEST_LEN));
+ smartlist_add(missing_id_digests, ds->v3_identity_digest);
+ }
+ } SMARTLIST_FOREACH_END(ds);
+
+ /*
+ * Next, if we have a consensus, scan through it and look for anything
+ * signed with a key from a cert we don't have. Those get downloaded
+ * by (fp,sk) pair, but if we don't know any certs at all for the fp
+ * (identity digest), and it's one of the trusted dir server certs
+ * we started off above or a pending download in pending_id, don't
+ * try to get it yet. Most likely, the one we'll get for that will
+ * have the right signing key too, and we'd just be downloading
+ * redundantly.
+ */
if (status) {
SMARTLIST_FOREACH_BEGIN(status->voters, networkstatus_voter_info_t *,
voter) {
@@@ -517,7 -724,28 +732,29 @@@
if (!cache &&
!trusteddirserver_get_by_v3_auth_digest(voter->identity_digest))
continue; /* We are not a cache, and we don't know this authority.*/
+
+ /*
+ * If we don't know *any* cert for this authority, and a download by ID
+ * is pending or we added it to missing_id_digests above, skip this
+ * one for now to avoid duplicate downloads.
+ */
cl = get_cert_list(voter->identity_digest);
+ if (smartlist_len(cl->certs) == 0) {
+ /* We have no certs at all for this one */
+
+ /* Do we have a download of one pending? */
+ if (digestmap_get(pending_id, voter->identity_digest))
+ continue;
+
+ /*
+ * Are we about to launch a download of one due to the trusted
+ * dir server check above?
+ */
- if (smartlist_digest_isin(missing_id_digests, voter->identity_digest))
++ if (smartlist_contains_digest(missing_id_digests,
++ voter->identity_digest))
+ continue;
+ }
+
SMARTLIST_FOREACH_BEGIN(voter->sigs, document_signature_t *, sig) {
cert = authority_cert_get_by_digests(voter->identity_digest,
sig->signing_key_digest);
diff --cc src/test/test_containers.c
index ca90162,5fee5c9..005e102
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@@ -782,50 -783,88 +783,132 @@@ test_container_order_functions(void
;
}
+static void
+test_di_map(void *arg)
+{
+ di_digest256_map_t *map = NULL;
+ const uint8_t key1[] = "In view of the fact that it was ";
+ const uint8_t key2[] = "superficially convincing, being ";
+ const uint8_t key3[] = "properly enciphered in a one-tim";
+ const uint8_t key4[] = "e cipher scheduled for use today";
+ char *v1 = tor_strdup(", it came close to causing a disaster...");
+ char *v2 = tor_strdup("I regret to have to advise you that the mission");
+ char *v3 = tor_strdup("was actually initiated...");
+ /* -- John Brunner, _The Shockwave Rider_ */
+
+ (void)arg;
+
+ /* Try searching on an empty map. */
+ tt_ptr_op(NULL, ==, dimap_search(map, key1, NULL));
+ tt_ptr_op(NULL, ==, dimap_search(map, key2, NULL));
+ tt_ptr_op(v3, ==, dimap_search(map, key2, v3));
+ dimap_free(map, NULL);
+ map = NULL;
+
+ /* Add a single entry. */
+ dimap_add_entry(&map, key1, v1);
+ tt_ptr_op(NULL, ==, dimap_search(map, key2, NULL));
+ tt_ptr_op(v3, ==, dimap_search(map, key2, v3));
+ tt_ptr_op(v1, ==, dimap_search(map, key1, NULL));
+
+ /* Now try it with three entries in the map. */
+ dimap_add_entry(&map, key2, v2);
+ dimap_add_entry(&map, key3, v3);
+ tt_ptr_op(v1, ==, dimap_search(map, key1, NULL));
+ tt_ptr_op(v2, ==, dimap_search(map, key2, NULL));
+ tt_ptr_op(v3, ==, dimap_search(map, key3, NULL));
+ tt_ptr_op(NULL, ==, dimap_search(map, key4, NULL));
+ tt_ptr_op(v1, ==, dimap_search(map, key4, v1));
+
+ done:
+ tor_free(v1);
+ tor_free(v2);
+ tor_free(v3);
+ dimap_free(map, NULL);
+}
+
+ /** Run unit tests for fp_pair-to-void* map functions */
+ static void
+ test_container_fp_pair_map(void)
+ {
+ fp_pair_map_t *map;
+ fp_pair_t fp1, fp2, fp3, fp4, fp5, fp6;
+ void *v;
+ fp_pair_map_iter_t *iter;
+ fp_pair_t k;
+
+ map = fp_pair_map_new();
+ test_assert(map);
+ test_eq(fp_pair_map_size(map), 0);
+ test_assert(fp_pair_map_isempty(map));
+
+ memset(fp1.first, 0x11, DIGEST_LEN);
+ memset(fp1.second, 0x12, DIGEST_LEN);
+ memset(fp2.first, 0x21, DIGEST_LEN);
+ memset(fp2.second, 0x22, DIGEST_LEN);
+ memset(fp3.first, 0x31, DIGEST_LEN);
+ memset(fp3.second, 0x32, DIGEST_LEN);
+ memset(fp4.first, 0x41, DIGEST_LEN);
+ memset(fp4.second, 0x42, DIGEST_LEN);
+ memset(fp5.first, 0x51, DIGEST_LEN);
+ memset(fp5.second, 0x52, DIGEST_LEN);
+ memset(fp6.first, 0x61, DIGEST_LEN);
+ memset(fp6.second, 0x62, DIGEST_LEN);
+
+ v = fp_pair_map_set(map, &fp1, (void*)99);
+ test_eq(v, NULL);
+ test_assert(!fp_pair_map_isempty(map));
+ v = fp_pair_map_set(map, &fp2, (void*)101);
+ test_eq(v, NULL);
+ v = fp_pair_map_set(map, &fp1, (void*)100);
+ test_eq(v, (void*)99);
+ test_eq_ptr(fp_pair_map_get(map, &fp1), (void*)100);
+ test_eq_ptr(fp_pair_map_get(map, &fp2), (void*)101);
+ test_eq_ptr(fp_pair_map_get(map, &fp3), NULL);
+ fp_pair_map_assert_ok(map);
+
+ v = fp_pair_map_remove(map, &fp2);
+ fp_pair_map_assert_ok(map);
+ test_eq_ptr(v, (void*)101);
+ test_eq_ptr(fp_pair_map_get(map, &fp2), NULL);
+ test_eq_ptr(fp_pair_map_remove(map, &fp2), NULL);
+
+ fp_pair_map_set(map, &fp2, (void*)101);
+ fp_pair_map_set(map, &fp3, (void*)102);
+ fp_pair_map_set(map, &fp4, (void*)103);
+ test_eq(fp_pair_map_size(map), 4);
+ fp_pair_map_assert_ok(map);
+ fp_pair_map_set(map, &fp5, (void*)104);
+ fp_pair_map_set(map, &fp6, (void*)105);
+ fp_pair_map_assert_ok(map);
+
+ /* Test iterator. */
+ iter = fp_pair_map_iter_init(map);
+ while (!fp_pair_map_iter_done(iter)) {
+ fp_pair_map_iter_get(iter, &k, &v);
+ test_eq_ptr(v, fp_pair_map_get(map, &k));
+
+ if (tor_memeq(&fp2, &k, sizeof(fp2))) {
+ iter = fp_pair_map_iter_next_rmv(map, iter);
+ } else {
+ iter = fp_pair_map_iter_next(map, iter);
+ }
+ }
+
+ /* Make sure we removed fp2, but not the others. */
+ test_eq_ptr(fp_pair_map_get(map, &fp2), NULL);
+ test_eq_ptr(fp_pair_map_get(map, &fp5), (void*)104);
+
+ fp_pair_map_assert_ok(map);
+ /* Clean up after ourselves. */
+ fp_pair_map_free(map, NULL);
+ map = NULL;
+
+ done:
+ if (map)
+ fp_pair_map_free(map, NULL);
+ }
+
#define CONTAINER_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_container_ ## name }
@@@ -840,7 -879,7 +923,8 @@@ struct testcase_t container_tests[] =
CONTAINER_LEGACY(strmap),
CONTAINER_LEGACY(pqueue),
CONTAINER_LEGACY(order_functions),
+ { "di_map", test_di_map, 0, NULL, NULL },
+ CONTAINER_LEGACY(fp_pair_map),
END_OF_TESTCASES
};
More information about the tor-commits
mailing list