summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/address.c19
-rw-r--r--src/common/address.h13
-rw-r--r--src/common/compat.c56
-rw-r--r--src/common/compat.h38
-rw-r--r--src/common/compat_libevent.c3
-rw-r--r--src/common/container.c45
-rw-r--r--src/common/container.h20
-rw-r--r--src/common/crypto.c63
-rw-r--r--src/common/crypto.h6
-rw-r--r--src/common/crypto_curve25519.c176
-rw-r--r--src/common/crypto_curve25519.h14
-rw-r--r--src/common/crypto_ed25519.c353
-rw-r--r--src/common/crypto_ed25519.h116
-rw-r--r--src/common/crypto_format.c22
-rw-r--r--src/common/crypto_pwbox.c187
-rw-r--r--src/common/crypto_pwbox.h20
-rw-r--r--src/common/crypto_s2k.c460
-rw-r--r--src/common/crypto_s2k.h73
-rw-r--r--src/common/di_ops.c2
-rw-r--r--src/common/include.am15
-rw-r--r--src/common/log.c20
-rw-r--r--src/common/sandbox.c170
-rw-r--r--src/common/sandbox.h36
-rw-r--r--src/common/torgzip.c68
-rw-r--r--src/common/torgzip.h3
-rw-r--r--src/common/torint.h20
-rw-r--r--src/common/torlog.h4
-rw-r--r--src/common/tortls.c19
-rw-r--r--src/common/util.c87
-rw-r--r--src/common/util.h3
-rw-r--r--src/common/util_process.c4
-rw-r--r--src/config/include.am2
-rw-r--r--src/config/torrc.minimal.in192
-rw-r--r--src/config/torrc.minimal.in-staging193
-rw-r--r--src/config/torrc.sample.in17
-rw-r--r--src/ext/OpenBSD_malloc_Linux.c12
-rw-r--r--src/ext/README12
-rw-r--r--src/ext/ed25519/ref10/Makefile41
-rw-r--r--src/ext/ed25519/ref10/README.tor23
-rw-r--r--src/ext/ed25519/ref10/api.h4
-rw-r--r--src/ext/ed25519/ref10/base.h1344
-rw-r--r--src/ext/ed25519/ref10/base.py65
-rw-r--r--src/ext/ed25519/ref10/base2.h40
-rw-r--r--src/ext/ed25519/ref10/base2.py60
-rw-r--r--src/ext/ed25519/ref10/blinding.c76
-rw-r--r--src/ext/ed25519/ref10/crypto_hash_sha512.h30
-rw-r--r--src/ext/ed25519/ref10/crypto_int32.h25
-rw-r--r--src/ext/ed25519/ref10/crypto_int64.h23
-rw-r--r--src/ext/ed25519/ref10/crypto_sign.h9
-rw-r--r--src/ext/ed25519/ref10/crypto_uint32.h3
-rw-r--r--src/ext/ed25519/ref10/crypto_uint64.h3
-rw-r--r--src/ext/ed25519/ref10/crypto_verify_32.h5
-rw-r--r--src/ext/ed25519/ref10/d.h1
-rw-r--r--src/ext/ed25519/ref10/d.py28
-rw-r--r--src/ext/ed25519/ref10/d2.h1
-rw-r--r--src/ext/ed25519/ref10/d2.py28
-rw-r--r--src/ext/ed25519/ref10/ed25519_ref10.h30
-rw-r--r--src/ext/ed25519/ref10/fe.h56
-rw-r--r--src/ext/ed25519/ref10/fe_0.c19
-rw-r--r--src/ext/ed25519/ref10/fe_1.c19
-rw-r--r--src/ext/ed25519/ref10/fe_add.c57
-rw-r--r--src/ext/ed25519/ref10/fe_cmov.c63
-rw-r--r--src/ext/ed25519/ref10/fe_copy.c29
-rw-r--r--src/ext/ed25519/ref10/fe_frombytes.c73
-rw-r--r--src/ext/ed25519/ref10/fe_invert.c14
-rw-r--r--src/ext/ed25519/ref10/fe_isnegative.c16
-rw-r--r--src/ext/ed25519/ref10/fe_isnonzero.c19
-rw-r--r--src/ext/ed25519/ref10/fe_mul.c253
-rw-r--r--src/ext/ed25519/ref10/fe_neg.c45
-rw-r--r--src/ext/ed25519/ref10/fe_pow22523.c13
-rw-r--r--src/ext/ed25519/ref10/fe_sq.c149
-rw-r--r--src/ext/ed25519/ref10/fe_sq2.c160
-rw-r--r--src/ext/ed25519/ref10/fe_sub.c57
-rw-r--r--src/ext/ed25519/ref10/fe_tobytes.c119
-rw-r--r--src/ext/ed25519/ref10/ge.h95
-rw-r--r--src/ext/ed25519/ref10/ge_add.c11
-rw-r--r--src/ext/ed25519/ref10/ge_add.h97
-rw-r--r--src/ext/ed25519/ref10/ge_add.q49
-rw-r--r--src/ext/ed25519/ref10/ge_double_scalarmult.c96
-rw-r--r--src/ext/ed25519/ref10/ge_frombytes.c50
-rw-r--r--src/ext/ed25519/ref10/ge_madd.c11
-rw-r--r--src/ext/ed25519/ref10/ge_madd.h88
-rw-r--r--src/ext/ed25519/ref10/ge_madd.q46
-rw-r--r--src/ext/ed25519/ref10/ge_msub.c11
-rw-r--r--src/ext/ed25519/ref10/ge_msub.h88
-rw-r--r--src/ext/ed25519/ref10/ge_msub.q46
-rw-r--r--src/ext/ed25519/ref10/ge_p1p1_to_p2.c12
-rw-r--r--src/ext/ed25519/ref10/ge_p1p1_to_p3.c13
-rw-r--r--src/ext/ed25519/ref10/ge_p2_0.c8
-rw-r--r--src/ext/ed25519/ref10/ge_p2_dbl.c11
-rw-r--r--src/ext/ed25519/ref10/ge_p2_dbl.h73
-rw-r--r--src/ext/ed25519/ref10/ge_p2_dbl.q41
-rw-r--r--src/ext/ed25519/ref10/ge_p3_0.c9
-rw-r--r--src/ext/ed25519/ref10/ge_p3_dbl.c12
-rw-r--r--src/ext/ed25519/ref10/ge_p3_to_cached.c17
-rw-r--r--src/ext/ed25519/ref10/ge_p3_to_p2.c12
-rw-r--r--src/ext/ed25519/ref10/ge_p3_tobytes.c14
-rw-r--r--src/ext/ed25519/ref10/ge_precomp_0.c8
-rw-r--r--src/ext/ed25519/ref10/ge_scalarmult_base.c109
-rw-r--r--src/ext/ed25519/ref10/ge_sub.c11
-rw-r--r--src/ext/ed25519/ref10/ge_sub.h97
-rw-r--r--src/ext/ed25519/ref10/ge_sub.q49
-rw-r--r--src/ext/ed25519/ref10/ge_tobytes.c14
-rw-r--r--src/ext/ed25519/ref10/keyconv.c37
-rw-r--r--src/ext/ed25519/ref10/keypair.c51
-rw-r--r--src/ext/ed25519/ref10/open.c42
-rw-r--r--src/ext/ed25519/ref10/pow22523.h161
-rw-r--r--src/ext/ed25519/ref10/pow22523.q61
-rw-r--r--src/ext/ed25519/ref10/pow225521.h161
-rw-r--r--src/ext/ed25519/ref10/pow225521.q61
-rwxr-xr-xsrc/ext/ed25519/ref10/q2h.sh4
-rw-r--r--src/ext/ed25519/ref10/randombytes.h4
-rw-r--r--src/ext/ed25519/ref10/sc.h15
-rw-r--r--src/ext/ed25519/ref10/sc_muladd.c368
-rw-r--r--src/ext/ed25519/ref10/sc_reduce.c275
-rw-r--r--src/ext/ed25519/ref10/sign.c29
-rw-r--r--src/ext/ed25519/ref10/sqrtm1.h1
-rw-r--r--src/ext/ed25519/ref10/sqrtm1.py28
-rw-r--r--src/ext/ht.h23
-rw-r--r--src/ext/include.am76
-rw-r--r--src/ext/trunnel/trunnel-impl.h310
-rw-r--r--src/ext/trunnel/trunnel.c246
-rw-r--r--src/ext/trunnel/trunnel.h64
-rw-r--r--src/include.am2
-rw-r--r--src/or/buffers.c20
-rw-r--r--src/or/channel.c4
-rw-r--r--src/or/circpathbias.c4
-rw-r--r--src/or/circuitbuild.c2
-rw-r--r--src/or/circuitlist.c254
-rw-r--r--src/or/circuitlist.h4
-rw-r--r--src/or/circuitmux.c6
-rw-r--r--src/or/circuitstats.c30
-rw-r--r--src/or/circuituse.c82
-rw-r--r--src/or/config.c171
-rw-r--r--src/or/connection.c54
-rw-r--r--src/or/connection_edge.c4
-rw-r--r--src/or/connection_or.c17
-rw-r--r--src/or/control.c51
-rw-r--r--src/or/cpuworker.c12
-rw-r--r--src/or/directory.c6
-rw-r--r--src/or/dirserv.c366
-rw-r--r--src/or/dirserv.h3
-rw-r--r--src/or/dirvote.c440
-rw-r--r--src/or/dirvote.h26
-rw-r--r--src/or/dns.c4
-rw-r--r--src/or/entrynodes.c269
-rw-r--r--src/or/entrynodes.h32
-rw-r--r--src/or/fp_pair.c6
-rw-r--r--src/or/geoip.c28
-rw-r--r--src/or/geoip.h8
-rw-r--r--src/or/hibernate.c51
-rw-r--r--src/or/hibernate.h1
-rw-r--r--src/or/main.c226
-rw-r--r--src/or/microdesc.c5
-rw-r--r--src/or/networkstatus.c12
-rw-r--r--src/or/nodelist.c16
-rw-r--r--src/or/nodelist.h5
-rw-r--r--src/or/ntmain.h2
-rw-r--r--src/or/or.h36
-rw-r--r--src/or/policies.c124
-rw-r--r--src/or/policies.h19
-rw-r--r--src/or/reasons.c4
-rw-r--r--src/or/relay.c5
-rw-r--r--src/or/rendclient.c4
-rw-r--r--src/or/rendcommon.c6
-rw-r--r--src/or/rendmid.c4
-rw-r--r--src/or/rendservice.c29
-rw-r--r--src/or/rephist.c19
-rw-r--r--src/or/router.c28
-rw-r--r--src/or/routerlist.c47
-rw-r--r--src/or/routerlist.h3
-rw-r--r--src/or/routerparse.c18
-rw-r--r--src/or/routerparse.h4
-rw-r--r--src/or/routerset.c39
-rw-r--r--src/or/routerset.h40
-rw-r--r--src/or/status.c14
-rw-r--r--src/or/transports.c113
-rw-r--r--src/or/transports.h6
-rw-r--r--src/test/bench.c62
-rw-r--r--src/test/ed25519_exts_ref.py234
-rw-r--r--src/test/ed25519_vectors.inc150
-rw-r--r--src/test/include.am9
-rw-r--r--src/test/slow_ed25519.py115
-rw-r--r--src/test/test.c322
-rw-r--r--src/test/test.h24
-rw-r--r--src/test/test_accounting.c76
-rw-r--r--src/test/test_addr.c424
-rw-r--r--src/test/test_bt_cl.c5
-rw-r--r--src/test/test_buffers.c110
-rw-r--r--src/test/test_cell_formats.c72
-rw-r--r--src/test/test_cell_queue.c8
-rw-r--r--src/test/test_circuitlist.c18
-rw-r--r--src/test/test_circuitmux.c2
-rw-r--r--src/test/test_config.c152
-rw-r--r--src/test/test_containers.c598
-rw-r--r--src/test/test_crypto.c1065
-rw-r--r--src/test/test_descriptors.inc305
-rw-r--r--src/test/test_dir.c966
-rw-r--r--src/test/test_entrynodes.c727
-rw-r--r--src/test/test_extorport.c36
-rw-r--r--src/test/test_hs.c16
-rw-r--r--src/test/test_introduce.c76
-rw-r--r--src/test/test_logging.c2
-rw-r--r--src/test/test_microdesc.c32
-rw-r--r--src/test/test_nodelist.c6
-rw-r--r--src/test/test_policy.c126
-rw-r--r--src/test/test_pt.c158
-rw-r--r--src/test/test_replay.c119
-rw-r--r--src/test/test_routerset.c2122
-rw-r--r--src/test/test_socks.c282
-rw-r--r--src/test/test_status.c28
-rw-r--r--src/test/test_util.c2153
-rw-r--r--src/tools/tor-gencert.c12
-rw-r--r--src/trunnel/include.am29
-rw-r--r--src/trunnel/pwbox.c515
-rw-r--r--src/trunnel/pwbox.h173
-rw-r--r--src/trunnel/pwbox.trunnel14
-rw-r--r--src/trunnel/trunnel-local.h18
-rw-r--r--src/win32/orconfig.h13
219 files changed, 18335 insertions, 4602 deletions
diff --git a/src/common/address.c b/src/common/address.c
index 8591f387e6..07b76597da 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -323,17 +323,23 @@ tor_addr_is_internal_(const tor_addr_t *addr, int for_listening,
{
uint32_t iph4 = 0;
uint32_t iph6[4];
- sa_family_t v_family;
tor_assert(addr);
- v_family = tor_addr_family(addr);
+ sa_family_t v_family = tor_addr_family(addr);
if (v_family == AF_INET) {
iph4 = tor_addr_to_ipv4h(addr);
} else if (v_family == AF_INET6) {
if (tor_addr_is_v4(addr)) { /* v4-mapped */
+ uint32_t *addr32 = NULL;
v_family = AF_INET;
- iph4 = ntohl(tor_addr_to_in6_addr32(addr)[3]);
+ // Work around an incorrect NULL pointer dereference warning in
+ // "clang --analyze" due to limited analysis depth
+ addr32 = tor_addr_to_in6_addr32(addr);
+ // To improve performance, wrap this assertion in:
+ // #if !defined(__clang_analyzer__) || PARANOIA
+ tor_assert(addr32);
+ iph4 = ntohl(addr32[3]);
}
}
@@ -465,7 +471,6 @@ tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
if (!strcasecmpend(address, ".ip6.arpa")) {
const char *cp;
- int i;
int n0, n1;
struct in6_addr in6;
@@ -473,7 +478,7 @@ tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
return -1;
cp = address;
- for (i = 0; i < 16; ++i) {
+ for (int i = 0; i < 16; ++i) {
n0 = hex_decode_digit(*cp++); /* The low-order nybble appears first. */
if (*cp++ != '.') return -1; /* Then a dot. */
n1 = hex_decode_digit(*cp++); /* The high-order nybble appears first. */
@@ -598,7 +603,7 @@ tor_addr_parse_mask_ports(const char *s,
int any_flag=0, v4map=0;
sa_family_t family;
struct in6_addr in6_tmp;
- struct in_addr in_tmp;
+ struct in_addr in_tmp = { .s_addr = 0 };
tor_assert(s);
tor_assert(addr_out);
@@ -659,7 +664,7 @@ tor_addr_parse_mask_ports(const char *s,
tor_addr_from_ipv4h(addr_out, 0);
any_flag = 1;
} else if (!strcmp(address, "*6") && (flags & TAPMP_EXTENDED_STAR)) {
- static char nil_bytes[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
+ static char nil_bytes[16] = { [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
family = AF_INET6;
tor_addr_from_ipv6_bytes(addr_out, nil_bytes);
any_flag = 1;
diff --git a/src/common/address.h b/src/common/address.h
index 8dc63b71c1..42844e8ad1 100644
--- a/src/common/address.h
+++ b/src/common/address.h
@@ -103,7 +103,18 @@ tor_addr_to_ipv4h(const tor_addr_t *a)
static INLINE uint32_t
tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
{
- return a->family == AF_INET6 ? ntohl(tor_addr_to_in6_addr32(a)[3]) : 0;
+ if (a->family == AF_INET6) {
+ uint32_t *addr32 = NULL;
+ // Work around an incorrect NULL pointer dereference warning in
+ // "clang --analyze" due to limited analysis depth
+ addr32 = tor_addr_to_in6_addr32(a);
+ // To improve performance, wrap this assertion in:
+ // #if !defined(__clang_analyzer__) || PARANOIA
+ tor_assert(addr32);
+ return ntohl(addr32[3]);
+ } else {
+ return 0;
+ }
}
/** Return the address family of <b>a</b>. Possible values are:
* AF_INET6, AF_INET, AF_UNSPEC. */
diff --git a/src/common/compat.c b/src/common/compat.c
index e25ecc462d..4dd04455a2 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -981,14 +981,23 @@ tor_fd_getpos(int fd)
#endif
}
-/** Move <b>fd</b> to the end of the file. Return -1 on error, 0 on success. */
+/** Move <b>fd</b> to the end of the file. Return -1 on error, 0 on success.
+ * If the file is a pipe, do nothing and succeed.
+ **/
int
tor_fd_seekend(int fd)
{
#ifdef _WIN32
return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
#else
- return lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
+ off_t rc = lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
+#ifdef ESPIPE
+ /* If we get an error and ESPIPE, then it's a pipe or a socket of a fifo:
+ * no need to worry. */
+ if (rc < 0 && errno == ESPIPE)
+ rc = 0;
+#endif
+ return (rc < 0) ? -1 : 0;
#endif
}
@@ -1004,6 +1013,23 @@ tor_fd_setpos(int fd, off_t pos)
#endif
}
+/** Replacement for ftruncate(fd, 0): move to the front of the file and remove
+ * all the rest of the file. Return -1 on error, 0 on success. */
+int
+tor_ftruncate(int fd)
+{
+ /* Rumor has it that some versions of ftruncate do not move the file pointer.
+ */
+ if (tor_fd_setpos(fd, 0) < 0)
+ return -1;
+
+#ifdef _WIN32
+ return _chsize(fd, 0);
+#else
+ return ftruncate(fd, 0);
+#endif
+}
+
#undef DEBUG_SOCKET_COUNTING
#ifdef DEBUG_SOCKET_COUNTING
/** A bitarray of all fds that should be passed to tor_socket_close(). Only
@@ -1409,6 +1435,9 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
socklen_t size;
int saved_errno = -1;
+ memset(&connect_addr, 0, sizeof(connect_addr));
+ memset(&listen_addr, 0, sizeof(listen_addr));
+
if (protocol
#ifdef AF_UNIX
|| family != AF_UNIX
@@ -1670,12 +1699,12 @@ log_credential_status(void)
/* log supplementary groups */
sup_gids_size = 64;
- sup_gids = tor_malloc(sizeof(gid_t) * 64);
+ sup_gids = tor_calloc(sizeof(gid_t), 64);
while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 &&
errno == EINVAL &&
sup_gids_size < NGROUPS_MAX) {
sup_gids_size *= 2;
- sup_gids = tor_realloc(sup_gids, sizeof(gid_t) * sup_gids_size);
+ sup_gids = tor_reallocarray(sup_gids, sizeof(gid_t), sup_gids_size);
}
if (ngids < 0) {
@@ -2485,14 +2514,12 @@ get_uname(void)
"Unrecognized version of Windows [major=%d,minor=%d]",
(int)info.dwMajorVersion,(int)info.dwMinorVersion);
}
-#if !defined (WINCE)
#ifdef VER_NT_SERVER
if (info.wProductType == VER_NT_SERVER ||
info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
strlcat(uname_result, " [server]", sizeof(uname_result));
}
#endif
-#endif
#else
strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
#endif
@@ -2697,15 +2724,8 @@ tor_gettimeofday(struct timeval *timeval)
uint64_t ft_64;
FILETIME ft_ft;
} ft;
-#if defined (WINCE)
- /* wince do not have GetSystemTimeAsFileTime */
- SYSTEMTIME stime;
- GetSystemTime(&stime);
- SystemTimeToFileTime(&stime,&ft.ft_ft);
-#else
/* number of 100-nsec units since Jan 1, 1601 */
GetSystemTimeAsFileTime(&ft.ft_ft);
-#endif
if (ft.ft_64 < EPOCH_BIAS) {
log_err(LD_GENERAL,"System time is before 1970; failing.");
exit(1);
@@ -2731,7 +2751,7 @@ tor_gettimeofday(struct timeval *timeval)
return;
}
-#if defined(TOR_IS_MULTITHREADED) && !defined(_WIN32)
+#if !defined(_WIN32)
/** Defined iff we need to add locks when defining fake versions of reentrant
* versions of time-related functions. */
#define TIME_FNS_NEED_LOCKS
@@ -2991,7 +3011,6 @@ tor_get_thread_id(void)
}
#endif
-#ifdef TOR_IS_MULTITHREADED
/** Return a newly allocated, ready-for-use mutex. */
tor_mutex_t *
tor_mutex_new(void)
@@ -3009,7 +3028,6 @@ tor_mutex_free(tor_mutex_t *m)
tor_mutex_uninit(m);
tor_free(m);
}
-#endif
/* Conditions. */
#ifdef USE_PTHREADS
@@ -3548,12 +3566,12 @@ get_total_system_memory(size_t *mem_out)
return 0;
}
-#if SIZE_T_MAX != UINT64_MAX
- if (m > SIZE_T_MAX) {
+#if SIZE_MAX != UINT64_MAX
+ if (m > SIZE_MAX) {
/* I think this could happen if we're a 32-bit Tor running on a 64-bit
* system: we could have more system memory than would fit in a
* size_t. */
- m = SIZE_T_MAX;
+ m = SIZE_MAX;
}
#endif
diff --git a/src/common/compat.h b/src/common/compat.h
index ec7d2415ed..852a432187 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -56,21 +56,6 @@
#include <stdio.h>
#include <errno.h>
-#if defined (WINCE)
-#include <fcntl.h>
-#include <io.h>
-#include <math.h>
-#include <projects.h>
-/* this is not exported as W .... */
-#define SHGetPathFromIDListW SHGetPathFromIDList
-/* wcecompat has vasprintf */
-#define HAVE_VASPRINTF
-/* no service here */
-#ifdef NT_SERVICE
-#undef NT_SERVICE
-#endif
-#endif // WINCE
-
#ifndef NULL_REP_IS_ZERO_BYTES
#error "It seems your platform does not represent NULL as zero. We can't cope."
#endif
@@ -423,6 +408,7 @@ void tor_lockfile_unlock(tor_lockfile_t *lockfile);
off_t tor_fd_getpos(int fd);
int tor_fd_setpos(int fd, off_t pos);
int tor_fd_seekend(int fd);
+int tor_ftruncate(int fd);
#ifdef _WIN32
#define PATH_SEPARATOR "\\"
@@ -648,15 +634,12 @@ int get_total_system_memory(size_t *mem_out);
int spawn_func(void (*func)(void *), void *data);
void spawn_exit(void) ATTR_NORETURN;
-#if defined(ENABLE_THREADS) && defined(_WIN32)
+#if defined(_WIN32)
#define USE_WIN32_THREADS
-#define TOR_IS_MULTITHREADED 1
-#elif (defined(ENABLE_THREADS) && defined(HAVE_PTHREAD_H) && \
- defined(HAVE_PTHREAD_CREATE))
+#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
#define USE_PTHREADS
-#define TOR_IS_MULTITHREADED 1
#else
-#undef TOR_IS_MULTITHREADED
+#error "No threading system was found"
#endif
int compute_num_cpus(void);
@@ -682,7 +665,6 @@ typedef struct tor_mutex_t {
int tor_mlockall(void);
-#ifdef TOR_IS_MULTITHREADED
tor_mutex_t *tor_mutex_new(void);
void tor_mutex_init(tor_mutex_t *m);
void tor_mutex_acquire(tor_mutex_t *m);
@@ -691,21 +673,10 @@ void tor_mutex_free(tor_mutex_t *m);
void tor_mutex_uninit(tor_mutex_t *m);
unsigned long tor_get_thread_id(void);
void tor_threads_init(void);
-#else
-#define tor_mutex_new() ((tor_mutex_t*)tor_malloc(sizeof(int)))
-#define tor_mutex_init(m) STMT_NIL
-#define tor_mutex_acquire(m) STMT_VOID(m)
-#define tor_mutex_release(m) STMT_NIL
-#define tor_mutex_free(m) STMT_BEGIN tor_free(m); STMT_END
-#define tor_mutex_uninit(m) STMT_NIL
-#define tor_get_thread_id() (1UL)
-#define tor_threads_init() STMT_NIL
-#endif
void set_main_thread(void);
int in_main_thread(void);
-#ifdef TOR_IS_MULTITHREADED
#if 0
typedef struct tor_cond_t tor_cond_t;
tor_cond_t *tor_cond_new(void);
@@ -714,7 +685,6 @@ int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex);
void tor_cond_signal_one(tor_cond_t *cond);
void tor_cond_signal_all(tor_cond_t *cond);
#endif
-#endif
/** Macros for MIN/MAX. Never use these when the arguments could have
* side-effects.
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index 74b54bb855..7e6f304c6b 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -210,6 +210,9 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
} else {
using_iocp_bufferevents = 0;
}
+#elif defined(__COVERITY__)
+ /* Avoid a 'dead code' warning below. */
+ using_threads = ! torcfg->disable_iocp;
#endif
if (!using_threads) {
diff --git a/src/common/container.c b/src/common/container.c
index b937d544fc..f7dfc69c2f 100644
--- a/src/common/container.c
+++ b/src/common/container.c
@@ -28,21 +28,21 @@
/** Allocate and return an empty smartlist.
*/
-smartlist_t *
-smartlist_new(void)
+MOCK_IMPL(smartlist_t *,
+smartlist_new,(void))
{
smartlist_t *sl = tor_malloc(sizeof(smartlist_t));
sl->num_used = 0;
sl->capacity = SMARTLIST_DEFAULT_CAPACITY;
- sl->list = tor_malloc(sizeof(void *) * sl->capacity);
+ sl->list = tor_calloc(sizeof(void *), sl->capacity);
return sl;
}
/** Deallocate a smartlist. Does not release storage associated with the
* list's elements.
*/
-void
-smartlist_free(smartlist_t *sl)
+MOCK_IMPL(void,
+smartlist_free,(smartlist_t *sl))
{
if (!sl)
return;
@@ -66,19 +66,28 @@ smartlist_ensure_capacity(smartlist_t *sl, int size)
#define MAX_CAPACITY (INT_MAX)
#else
#define MAX_CAPACITY (int)((SIZE_MAX / (sizeof(void*))))
+#define ASSERT_CAPACITY
#endif
if (size > sl->capacity) {
int higher = sl->capacity;
if (PREDICT_UNLIKELY(size > MAX_CAPACITY/2)) {
+#ifdef ASSERT_CAPACITY
+ /* We don't include this assertion when MAX_CAPACITY == INT_MAX,
+ * since int size; (size <= INT_MAX) makes analysis tools think we're
+ * doing something stupid. */
tor_assert(size <= MAX_CAPACITY);
+#endif
higher = MAX_CAPACITY;
} else {
while (size > higher)
higher *= 2;
}
sl->capacity = higher;
- sl->list = tor_realloc(sl->list, sizeof(void*)*((size_t)sl->capacity));
+ sl->list = tor_reallocarray(sl->list, sizeof(void *),
+ ((size_t)sl->capacity));
}
+#undef ASSERT_CAPACITY
+#undef MAX_CAPACITY
}
/** Append element to the end of the list. */
@@ -1043,18 +1052,18 @@ digestmap_entry_hash(const digestmap_entry_t *a)
HT_PROTOTYPE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
strmap_entries_eq)
-HT_GENERATE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
- strmap_entries_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(strmap_impl, strmap_entry_t, node, strmap_entry_hash,
+ strmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
HT_PROTOTYPE(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
digestmap_entries_eq)
-HT_GENERATE(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
- digestmap_entries_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(digestmap_impl, digestmap_entry_t, node, digestmap_entry_hash,
+ digestmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
/** Constructor to create a new empty map from strings to void*'s.
*/
-strmap_t *
-strmap_new(void)
+MOCK_IMPL(strmap_t *,
+strmap_new,(void))
{
strmap_t *result;
result = tor_malloc(sizeof(strmap_t));
@@ -1064,8 +1073,8 @@ strmap_new(void)
/** Constructor to create a new empty map from digests to void*'s.
*/
-digestmap_t *
-digestmap_new(void)
+MOCK_IMPL(digestmap_t *,
+digestmap_new,(void))
{
digestmap_t *result;
result = tor_malloc(sizeof(digestmap_t));
@@ -1418,8 +1427,8 @@ digestmap_iter_done(digestmap_iter_t *iter)
* entries. If free_val is provided, it is invoked on every value in
* <b>map</b>.
*/
-void
-strmap_free(strmap_t *map, void (*free_val)(void*))
+MOCK_IMPL(void,
+strmap_free,(strmap_t *map, void (*free_val)(void*)))
{
strmap_entry_t **ent, **next, *this;
if (!map)
@@ -1442,8 +1451,8 @@ strmap_free(strmap_t *map, void (*free_val)(void*))
* entries. If free_val is provided, it is invoked on every value in
* <b>map</b>.
*/
-void
-digestmap_free(digestmap_t *map, void (*free_val)(void*))
+MOCK_IMPL(void,
+digestmap_free, (digestmap_t *map, void (*free_val)(void*)))
{
digestmap_entry_t **ent, **next, *this;
if (!map)
diff --git a/src/common/container.h b/src/common/container.h
index 0d31f2093b..c3756c83a6 100644
--- a/src/common/container.h
+++ b/src/common/container.h
@@ -27,8 +27,8 @@ typedef struct smartlist_t {
/** @} */
} smartlist_t;
-smartlist_t *smartlist_new(void);
-void smartlist_free(smartlist_t *sl);
+MOCK_DECL(smartlist_t *, smartlist_new, (void));
+MOCK_DECL(void, smartlist_free, (smartlist_t *sl));
void smartlist_clear(smartlist_t *sl);
void smartlist_add(smartlist_t *sl, void *element);
void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2);
@@ -328,11 +328,11 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join,
#define DECLARE_MAP_FNS(maptype, keytype, prefix) \
typedef struct maptype maptype; \
typedef struct prefix##entry_t *prefix##iter_t; \
- maptype* prefix##new(void); \
+ MOCK_DECL(maptype*, prefix##new, (void)); \
void* prefix##set(maptype *map, keytype key, void *val); \
void* prefix##get(const maptype *map, keytype key); \
void* prefix##remove(maptype *map, keytype key); \
- void prefix##free(maptype *map, void (*free_val)(void*)); \
+ MOCK_DECL(void, prefix##free, (maptype *map, void (*free_val)(void*))); \
int prefix##isempty(const maptype *map); \
int prefix##size(const maptype *map); \
prefix##iter_t *prefix##iter_init(maptype *map); \
@@ -473,7 +473,7 @@ void* strmap_remove_lc(strmap_t *map, const char *key);
#define DECLARE_TYPED_DIGESTMAP_FNS(prefix, maptype, valtype) \
typedef struct maptype maptype; \
- typedef struct prefix##iter_t prefix##iter_t; \
+ typedef struct prefix##iter_t *prefix##iter_t; \
ATTR_UNUSED static INLINE maptype* \
prefix##new(void) \
{ \
@@ -563,7 +563,7 @@ bitarray_init_zero(unsigned int n_bits)
{
/* round up to the next int. */
size_t sz = (n_bits+BITARRAY_MASK) >> BITARRAY_SHIFT;
- return tor_malloc_zero(sz*sizeof(unsigned int));
+ return tor_calloc(sz, sizeof(unsigned int));
}
/** Expand <b>ba</b> from holding <b>n_bits_old</b> to <b>n_bits_new</b>,
* clearing all new bits. Returns a possibly changed pointer to the
@@ -577,7 +577,7 @@ bitarray_expand(bitarray_t *ba,
char *ptr;
if (sz_new <= sz_old)
return ba;
- ptr = tor_realloc(ba, sz_new*sizeof(unsigned int));
+ ptr = tor_reallocarray(ba, sz_new, sizeof(unsigned int));
/* This memset does nothing to the older excess bytes. But they were
* already set to 0 by bitarry_init_zero. */
memset(ptr+sz_old*sizeof(unsigned int), 0,
@@ -689,5 +689,11 @@ median_int32(int32_t *array, int n_elements)
return find_nth_int32(array, n_elements, (n_elements-1)/2);
}
+static INLINE uint32_t
+third_quartile_uint32(uint32_t *array, int n_elements)
+{
+ return find_nth_uint32(array, n_elements, (n_elements*3)/4);
+}
+
#endif
diff --git a/src/common/crypto.c b/src/common/crypto.c
index a247a87d48..fa91f6dd82 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -75,12 +75,10 @@
/** Macro: is k a valid RSA private key? */
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)
-#ifdef TOR_IS_MULTITHREADED
/** A number of preallocated mutexes for use by OpenSSL. */
static tor_mutex_t **openssl_mutexes_ = NULL;
/** How many mutexes have we allocated for use by OpenSSL? */
static int n_openssl_mutexes_ = 0;
-#endif
/** A public key, or a public/private key-pair. */
struct crypto_pk_t
@@ -1840,7 +1838,7 @@ crypto_store_dynamic_dh_modulus(const char *fname)
goto done;
}
- base64_encoded_dh = tor_malloc_zero(len * 2); /* should be enough */
+ base64_encoded_dh = tor_calloc(len, 2); /* should be enough */
new_len = base64_encode(base64_encoded_dh, len * 2,
(char *)dh_string_repr, len);
if (new_len < 0) {
@@ -3003,50 +3001,6 @@ base32_decode(char *dest, size_t destlen, const char *src, size_t srclen)
return 0;
}
-/** Implement RFC2440-style iterated-salted S2K conversion: convert the
- * <b>secret_len</b>-byte <b>secret</b> into a <b>key_out_len</b> byte
- * <b>key_out</b>. As in RFC2440, the first 8 bytes of s2k_specifier
- * are a salt; the 9th byte describes how much iteration to do.
- * Does not support <b>key_out_len</b> &gt; DIGEST_LEN.
- */
-void
-secret_to_key(char *key_out, size_t key_out_len, const char *secret,
- size_t secret_len, const char *s2k_specifier)
-{
- crypto_digest_t *d;
- uint8_t c;
- size_t count, tmplen;
- char *tmp;
- tor_assert(key_out_len < SIZE_T_CEILING);
-
-#define EXPBIAS 6
- c = s2k_specifier[8];
- count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
-#undef EXPBIAS
-
- tor_assert(key_out_len <= DIGEST_LEN);
-
- d = crypto_digest_new();
- tmplen = 8+secret_len;
- tmp = tor_malloc(tmplen);
- memcpy(tmp,s2k_specifier,8);
- memcpy(tmp+8,secret,secret_len);
- secret_len += 8;
- while (count) {
- if (count >= secret_len) {
- crypto_digest_add_bytes(d, tmp, secret_len);
- count -= secret_len;
- } else {
- crypto_digest_add_bytes(d, tmp, count);
- count = 0;
- }
- }
- crypto_digest_get_digest(d, key_out, key_out_len);
- memwipe(tmp, 0, tmplen);
- tor_free(tmp);
- crypto_digest_free(d);
-}
-
/**
* Destroy the <b>sz</b> bytes of data stored at <b>mem</b>, setting them to
* the value <b>byte</b>.
@@ -3090,8 +3044,6 @@ memwipe(void *mem, uint8_t byte, size_t sz)
memset(mem, byte, sz);
}
-#ifdef TOR_IS_MULTITHREADED
-
#ifndef OPENSSL_THREADS
#error OpenSSL has been built without thread support. Tor requires an \
OpenSSL library with thread support enabled.
@@ -3168,7 +3120,7 @@ setup_openssl_threading(void)
int i;
int n = CRYPTO_num_locks();
n_openssl_mutexes_ = n;
- openssl_mutexes_ = tor_malloc(n*sizeof(tor_mutex_t *));
+ openssl_mutexes_ = tor_calloc(n, sizeof(tor_mutex_t *));
for (i=0; i < n; ++i)
openssl_mutexes_[i] = tor_mutex_new();
CRYPTO_set_locking_callback(openssl_locking_cb_);
@@ -3178,13 +3130,6 @@ setup_openssl_threading(void)
CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy_cb_);
return 0;
}
-#else
-static int
-setup_openssl_threading(void)
-{
- return 0;
-}
-#endif
/** Uninitialize the crypto library. Return 0 on success, -1 on failure.
*/
@@ -3208,7 +3153,7 @@ crypto_global_cleanup(void)
CONF_modules_unload(1);
CRYPTO_cleanup_all_ex_data();
-#ifdef TOR_IS_MULTITHREADED
+
if (n_openssl_mutexes_) {
int n = n_openssl_mutexes_;
tor_mutex_t **ms = openssl_mutexes_;
@@ -3220,7 +3165,7 @@ crypto_global_cleanup(void)
}
tor_free(ms);
}
-#endif
+
tor_free(crypto_openssl_version_str);
tor_free(crypto_openssl_header_version_str);
return 0;
diff --git a/src/common/crypto.h b/src/common/crypto.h
index aa4271aa33..39bbdb5717 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -280,12 +280,6 @@ int digest_from_base64(char *digest, const char *d64);
int digest256_to_base64(char *d64, const char *digest);
int digest256_from_base64(char *digest, const char *d64);
-/** Length of RFC2440-style S2K specifier: the first 8 bytes are a salt, the
- * 9th describes how much iteration to do. */
-#define S2K_SPECIFIER_LEN 9
-void secret_to_key(char *key_out, size_t key_out_len, const char *secret,
- size_t secret_len, const char *s2k_specifier);
-
/** OpenSSL-based utility functions. */
void memwipe(void *mem, uint8_t byte, size_t sz);
diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c
index 9e83440e16..8b8e560c89 100644
--- a/src/common/crypto_curve25519.c
+++ b/src/common/crypto_curve25519.c
@@ -8,6 +8,7 @@
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
+#include "container.h"
#include "crypto.h"
#include "crypto_curve25519.h"
#include "util.h"
@@ -63,26 +64,44 @@ curve25519_public_key_is_ok(const curve25519_public_key_t *key)
return !safe_mem_is_zero(key->public_key, CURVE25519_PUBKEY_LEN);
}
-/** Generate a new keypair and return the secret key. If <b>extra_strong</b>
- * is true, this key is possibly going to get used more than once, so
- * use a better-than-usual RNG. Return 0 on success, -1 on failure. */
+/**
+ * Generate CURVE25519_SECKEY_LEN random bytes in <b>out</b>. If
+ * <b>extra_strong</b> is true, this key is possibly going to get used more
+ * than once, so use a better-than-usual RNG. Return 0 on success, -1 on
+ * failure.
+ *
+ * This function does not adjust the output of the RNG at all; the will caller
+ * will need to clear or set the appropriate bits to make curve25519 work.
+ */
int
-curve25519_secret_key_generate(curve25519_secret_key_t *key_out,
- int extra_strong)
+curve25519_rand_seckey_bytes(uint8_t *out, int extra_strong)
{
uint8_t k_tmp[CURVE25519_SECKEY_LEN];
- if (crypto_rand((char*)key_out->secret_key, CURVE25519_SECKEY_LEN) < 0)
+ if (crypto_rand((char*)out, CURVE25519_SECKEY_LEN) < 0)
return -1;
if (extra_strong && !crypto_strongest_rand(k_tmp, CURVE25519_SECKEY_LEN)) {
/* If they asked for extra-strong entropy and we have some, use it as an
* HMAC key to improve not-so-good entropy rather than using it directly,
* just in case the extra-strong entropy is less amazing than we hoped. */
- crypto_hmac_sha256((char *)key_out->secret_key,
- (const char *)k_tmp, sizeof(k_tmp),
- (const char *)key_out->secret_key, CURVE25519_SECKEY_LEN);
+ crypto_hmac_sha256((char*) out,
+ (const char *)k_tmp, sizeof(k_tmp),
+ (const char *)out, CURVE25519_SECKEY_LEN);
}
memwipe(k_tmp, 0, sizeof(k_tmp));
+ return 0;
+}
+
+/** Generate a new keypair and return the secret key. If <b>extra_strong</b>
+ * is true, this key is possibly going to get used more than once, so
+ * use a better-than-usual RNG. Return 0 on success, -1 on failure. */
+int
+curve25519_secret_key_generate(curve25519_secret_key_t *key_out,
+ int extra_strong)
+{
+ if (curve25519_rand_seckey_bytes(key_out->secret_key, extra_strong) < 0)
+ return -1;
+
key_out->secret_key[0] &= 248;
key_out->secret_key[31] &= 127;
key_out->secret_key[31] |= 64;
@@ -109,69 +128,144 @@ curve25519_keypair_generate(curve25519_keypair_t *keypair_out,
return 0;
}
+/** Write the <b>datalen</b> bytes from <b>data</b> to the file named
+ * <b>fname</b> in the tagged-data format. This format contains a
+ * 32-byte header, followed by the data itself. The header is the
+ * NUL-padded string "== <b>typestring</b>: <b>tag</b> ==". The length
+ * of <b>typestring</b> and <b>tag</b> must therefore be no more than
+ * 24.
+ **/
int
-curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
- const char *fname,
- const char *tag)
+crypto_write_tagged_contents_to_file(const char *fname,
+ const char *typestring,
+ const char *tag,
+ const uint8_t *data,
+ size_t datalen)
{
- char contents[32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
- int r;
+ char header[32];
+ smartlist_t *chunks = smartlist_new();
+ sized_chunk_t ch0, ch1;
+ int r = -1;
- memset(contents, 0, sizeof(contents));
- tor_snprintf(contents, sizeof(contents), "== c25519v1: %s ==", tag);
- tor_assert(strlen(contents) <= 32);
- memcpy(contents+32, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN);
- memcpy(contents+32+CURVE25519_SECKEY_LEN,
- keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN);
+ memset(header, 0, sizeof(header));
+ if (tor_snprintf(header, sizeof(header),
+ "== %s: %s ==", typestring, tag) < 0)
+ goto end;
+ ch0.bytes = header;
+ ch0.len = 32;
+ ch1.bytes = (const char*) data;
+ ch1.len = datalen;
+ smartlist_add(chunks, &ch0);
+ smartlist_add(chunks, &ch1);
- r = write_bytes_to_file(fname, contents, sizeof(contents), 1);
+ r = write_chunks_to_file(fname, chunks, 1, 0);
- memwipe(contents, 0, sizeof(contents));
+ end:
+ smartlist_free(chunks);
return r;
}
-int
-curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
- char **tag_out,
- const char *fname)
+/** Read a tagged-data file from <b>fname</b> into the
+ * <b>data_out_len</b>-byte buffer in <b>data_out</b>. Check that the
+ * typestring matches <b>typestring</b>; store the tag into a newly allocated
+ * string in <b>tag_out</b>. Return -1 on failure, and the number of bytes of
+ * data on success. */
+ssize_t
+crypto_read_tagged_contents_from_file(const char *fname,
+ const char *typestring,
+ char **tag_out,
+ uint8_t *data_out,
+ ssize_t data_out_len)
{
char prefix[33];
- char *content;
+ char *content = NULL;
struct stat st;
- int r = -1;
+ ssize_t r = -1;
+ size_t st_size = 0;
*tag_out = NULL;
-
st.st_size = 0;
content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
if (! content)
goto end;
- if (st.st_size != 32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN)
+ if (st.st_size < 32 || st.st_size > 32 + data_out_len)
goto end;
+ st_size = (size_t)st.st_size;
memcpy(prefix, content, 32);
- prefix[32] = '\0';
- if (strcmpstart(prefix, "== c25519v1: ") ||
- strcmpend(prefix, " =="))
+ prefix[32] = 0;
+ /* Check type, extract tag. */
+ if (strcmpstart(prefix, "== ") || strcmpend(prefix, " ==") ||
+ ! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix)))
+ goto end;
+
+ if (strcmpstart(prefix+3, typestring) ||
+ 3+strlen(typestring) >= 32 ||
+ strcmpstart(prefix+3+strlen(typestring), ": "))
goto end;
- *tag_out = tor_strndup(prefix+strlen("== c25519v1: "),
- strlen(prefix) - strlen("== c25519v1: =="));
+ *tag_out = tor_strndup(prefix+5+strlen(typestring),
+ strlen(prefix)-8-strlen(typestring));
+
+ memcpy(data_out, content+32, st_size-32);
+ r = st_size - 32;
+
+ end:
+ if (content)
+ memwipe(content, 0, st_size);
+ tor_free(content);
+ return r;
+}
+
+/** DOCDOC */
+int
+curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
+ const char *fname,
+ const char *tag)
+{
+ uint8_t contents[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
+ int r;
+
+ memcpy(contents, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN);
+ memcpy(contents+CURVE25519_SECKEY_LEN,
+ keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN);
+
+ r = crypto_write_tagged_contents_to_file(fname,
+ "c25519v1",
+ tag,
+ contents,
+ sizeof(contents));
+
+ memwipe(contents, 0, sizeof(contents));
+ return r;
+}
+
+/** DOCDOC */
+int
+curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
+ char **tag_out,
+ const char *fname)
+{
+ uint8_t content[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
+ ssize_t len;
+ int r = -1;
+
+ len = crypto_read_tagged_contents_from_file(fname, "c25519v1", tag_out,
+ content, sizeof(content));
+ if (len != sizeof(content))
+ goto end;
- memcpy(keypair_out->seckey.secret_key, content+32, CURVE25519_SECKEY_LEN);
+ memcpy(keypair_out->seckey.secret_key, content, CURVE25519_SECKEY_LEN);
curve25519_public_key_generate(&keypair_out->pubkey, &keypair_out->seckey);
if (tor_memneq(keypair_out->pubkey.public_key,
- content + 32 + CURVE25519_SECKEY_LEN,
+ content + CURVE25519_SECKEY_LEN,
CURVE25519_PUBKEY_LEN))
goto end;
r = 0;
end:
- if (content) {
- memwipe(content, 0, (size_t) st.st_size);
- tor_free(content);
- }
+ memwipe(content, 0, sizeof(content));
if (r != 0) {
memset(keypair_out, 0, sizeof(*keypair_out));
tor_free(*tag_out);
diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h
index 57018ac2f5..404f99c18e 100644
--- a/src/common/crypto_curve25519.h
+++ b/src/common/crypto_curve25519.h
@@ -57,6 +57,8 @@ int curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
char **tag_out,
const char *fname);
+int curve25519_rand_seckey_bytes(uint8_t *out, int extra_strong);
+
#ifdef CRYPTO_CURVE25519_PRIVATE
STATIC int curve25519_impl(uint8_t *output, const uint8_t *secret,
const uint8_t *basepoint);
@@ -70,5 +72,17 @@ int curve25519_public_from_base64(curve25519_public_key_t *pkey,
int curve25519_public_to_base64(char *output,
const curve25519_public_key_t *pkey);
+int crypto_write_tagged_contents_to_file(const char *fname,
+ const char *typestring,
+ const char *tag,
+ const uint8_t *data,
+ size_t datalen);
+
+ssize_t crypto_read_tagged_contents_from_file(const char *fname,
+ const char *typestring,
+ char **tag_out,
+ uint8_t *data_out,
+ ssize_t data_out_len);
+
#endif
diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c
new file mode 100644
index 0000000000..408c12b4fd
--- /dev/null
+++ b/src/common/crypto_ed25519.c
@@ -0,0 +1,353 @@
+/* Copyright (c) 2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/* Wrapper code for an ed25519 implementation. */
+
+#include "orconfig.h"
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "crypto.h"
+
+#include "crypto_curve25519.h"
+#include "crypto_ed25519.h"
+#include "torlog.h"
+#include "util.h"
+
+#include "ed25519/ref10/ed25519_ref10.h"
+
+#include <openssl/sha.h>
+
+/**
+ * Initialize a new ed25519 secret key in <b>seckey_out</b>. If
+ * <b>extra_strong</b>, take the RNG inputs directly from the operating
+ * system. Return 0 on success, -1 on failure.
+ */
+int
+ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
+ int extra_strong)
+{
+ int r;
+ uint8_t seed[32];
+ if (! extra_strong || crypto_strongest_rand(seed, sizeof(seed)) < 0)
+ crypto_rand((char*)seed, sizeof(seed));
+
+ r = ed25519_ref10_seckey_expand(seckey_out->seckey, seed);
+ memwipe(seed, 0, sizeof(seed));
+
+ return r < 0 ? -1 : 0;
+}
+
+/**
+ * Given a 32-byte random seed in <b>seed</b>, expand it into an ed25519
+ * secret key in <b>seckey_out</b>. Return 0 on success, -1 on failure.
+ */
+int
+ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out,
+ const uint8_t *seed)
+{
+ if (ed25519_ref10_seckey_expand(seckey_out->seckey, seed) < 0)
+ return -1;
+ return 0;
+}
+
+/**
+ * Given a secret key in <b>seckey</b>, expand it into an
+ * ed25519 public key. Return 0 on success, -1 on failure.
+ */
+int
+ed25519_public_key_generate(ed25519_public_key_t *pubkey_out,
+ const ed25519_secret_key_t *seckey)
+{
+ if (ed25519_ref10_pubkey(pubkey_out->pubkey, seckey->seckey) < 0)
+ return -1;
+ return 0;
+}
+
+/** Generate a new ed25519 keypair in <b>keypair_out</b>. If
+ * <b>extra_strong</b> is set, try to mix some system entropy into the key
+ * generation process. Return 0 on success, -1 on failure. */
+int
+ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
+{
+ if (ed25519_secret_key_generate(&keypair_out->seckey, extra_strong) < 0)
+ return -1;
+ if (ed25519_public_key_generate(&keypair_out->pubkey,
+ &keypair_out->seckey)<0)
+ return -1;
+ return 0;
+}
+
+/**
+ * Set <b>signature_out</b> to a signature of the <b>len</b>-byte message
+ * <b>msg</b>, using the secret and public key in <b>keypair</b>.
+ */
+int
+ed25519_sign(ed25519_signature_t *signature_out,
+ const uint8_t *msg, size_t len,
+ const ed25519_keypair_t *keypair)
+{
+
+ if (ed25519_ref10_sign(signature_out->sig, msg, len,
+ keypair->seckey.seckey,
+ keypair->pubkey.pubkey) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check whether if <b>signature</b> is a valid signature for the
+ * <b>len</b>-byte message in <b>msg</b> made with the key <b>pubkey</b>.
+ *
+ * Return 0 if the signature is valid; -1 if it isn't.
+ */
+int
+ed25519_checksig(const ed25519_signature_t *signature,
+ const uint8_t *msg, size_t len,
+ const ed25519_public_key_t *pubkey)
+{
+ return
+ ed25519_ref10_open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
+}
+
+/** Validate every signature among those in <b>checkable</b>, which contains
+ * exactly <b>n_checkable</b> elements. If <b>okay_out</b> is non-NULL, set
+ * the i'th element of <b>okay_out</b> to 1 if the i'th element of
+ * <b>checkable</b> is valid, and to 0 otherwise. Return 0 if every signature
+ * was valid. Otherwise return -N, where N is the number of invalid
+ * signatures.
+ */
+int
+ed25519_checksig_batch(int *okay_out,
+ const ed25519_checkable_t *checkable,
+ int n_checkable)
+{
+ int res, i;
+
+ res = 0;
+ for (i = 0; i < n_checkable; ++i) {
+ const ed25519_checkable_t *ch = &checkable[i];
+ int r = ed25519_checksig(&ch->signature, ch->msg, ch->len, ch->pubkey);
+ if (r < 0)
+ --res;
+ if (okay_out)
+ okay_out[i] = (r == 0);
+ }
+
+#if 0
+ /* This is how we'd do it if we were using ed25519_donna. I'll keep this
+ * code around here in case we ever do that. */
+ const uint8_t **ms;
+ size_t *lens;
+ const uint8_t **pks;
+ const uint8_t **sigs;
+ int *oks;
+
+ ms = tor_malloc(sizeof(uint8_t*)*n_checkable);
+ lens = tor_malloc(sizeof(size_t)*n_checkable);
+ pks = tor_malloc(sizeof(uint8_t*)*n_checkable);
+ sigs = tor_malloc(sizeof(uint8_t*)*n_checkable);
+ oks = okay_out ? okay_out : tor_malloc(sizeof(int)*n_checkable);
+
+ for (i = 0; i < n_checkable; ++i) {
+ ms[i] = checkable[i].msg;
+ lens[i] = checkable[i].len;
+ pks[i] = checkable[i].pubkey->pubkey;
+ sigs[i] = checkable[i].signature.sig;
+ oks[i] = 0;
+ }
+
+ ed25519_sign_open_batch_donna_fb(ms, lens, pks, sigs, n_checkable, oks);
+
+ res = 0;
+ for (i = 0; i < n_checkable; ++i) {
+ if (!oks[i])
+ --res;
+ }
+
+ tor_free(ms);
+ tor_free(lens);
+ tor_free(pks);
+ if (! okay_out)
+ tor_free(oks);
+#endif
+
+ return res;
+}
+
+/**
+ * Given a curve25519 keypair in <b>inp</b>, generate a corresponding
+ * ed25519 keypair in <b>out</b>, and set <b>signbit_out</b> to the
+ * sign bit of the X coordinate of the ed25519 key.
+ *
+ * NOTE THAT IT IS PROBABLY NOT SAFE TO USE THE GENERATED KEY FOR ANYTHING
+ * OUTSIDE OF WHAT'S PRESENTED IN PROPOSAL 228. In particular, it's probably
+ * not a great idea to use it to sign attacker-supplied anything.
+ */
+int
+ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out,
+ int *signbit_out,
+ const curve25519_keypair_t *inp)
+{
+ const char string[] = "Derive high part of ed25519 key from curve25519 key";
+ ed25519_public_key_t pubkey_check;
+ SHA512_CTX ctx;
+ uint8_t sha512_output[64];
+
+ memcpy(out->seckey.seckey, inp->seckey.secret_key, 32);
+ SHA512_Init(&ctx);
+ SHA512_Update(&ctx, out->seckey.seckey, 32);
+ SHA512_Update(&ctx, string, sizeof(string));
+ SHA512_Final(sha512_output, &ctx);
+ memcpy(out->seckey.seckey + 32, sha512_output, 32);
+
+ ed25519_public_key_generate(&out->pubkey, &out->seckey);
+
+ *signbit_out = out->pubkey.pubkey[31] >> 7;
+
+ ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey,
+ *signbit_out);
+
+ tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
+
+ memwipe(&pubkey_check, 0, sizeof(pubkey_check));
+ memwipe(&ctx, 0, sizeof(ctx));
+ memwipe(sha512_output, 0, sizeof(sha512_output));
+
+ return 0;
+}
+
+/**
+ * Given a curve25519 public key and sign bit of X coordinate of the ed25519
+ * public key, generate the corresponding ed25519 public key.
+ */
+int
+ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey,
+ const curve25519_public_key_t *pubkey_in,
+ int signbit)
+{
+ return ed25519_ref10_pubkey_from_curve25519_pubkey(pubkey->pubkey,
+ pubkey_in->public_key,
+ signbit);
+}
+
+/**
+ * Given an ed25519 keypair in <b>inp</b>, generate a corresponding
+ * ed25519 keypair in <b>out</b>, blinded by the corresponding 32-byte input
+ * in 'param'.
+ *
+ * Tor uses key blinding for the "next-generation" hidden services design:
+ * service descriptors are encrypted with a key derived from the service's
+ * long-term public key, and then signed with (and stored at a position
+ * indexed by) a short-term key derived by blinding the long-term keys.
+ */
+int
+ed25519_keypair_blind(ed25519_keypair_t *out,
+ const ed25519_keypair_t *inp,
+ const uint8_t *param)
+{
+ ed25519_public_key_t pubkey_check;
+
+ ed25519_ref10_blind_secret_key(out->seckey.seckey,
+ inp->seckey.seckey, param);
+
+ ed25519_public_blind(&pubkey_check, &inp->pubkey, param);
+ ed25519_public_key_generate(&out->pubkey, &out->seckey);
+
+ tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
+
+ memwipe(&pubkey_check, 0, sizeof(pubkey_check));
+
+ return 0;
+}
+
+/**
+ * Given an ed25519 public key in <b>inp</b>, generate a corresponding blinded
+ * public key in <b>out</b>, blinded with the 32-byte parameter in
+ * <b>param</b>. Return 0 on sucess, -1 on railure.
+ */
+int
+ed25519_public_blind(ed25519_public_key_t *out,
+ const ed25519_public_key_t *inp,
+ const uint8_t *param)
+{
+ ed25519_ref10_blind_public_key(out->pubkey, inp->pubkey, param);
+ return 0;
+}
+
+/**
+ * Store seckey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
+ * Return 0 on success, -1 on failure.
+ */
+int
+ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
+ const char *filename,
+ const char *tag)
+{
+ return crypto_write_tagged_contents_to_file(filename,
+ "ed25519v1-secret",
+ tag,
+ seckey->seckey,
+ sizeof(seckey->seckey));
+}
+
+/**
+ * Read seckey unencrypted from <b>filename</b>, storing it into
+ * <b>seckey_out</b>. Set *<b>tag_out</> to the tag it was marked with.
+ * Return 0 on success, -1 on failure.
+ */
+int
+ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
+ char **tag_out,
+ const char *filename)
+{
+ ssize_t len;
+
+ len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-secret",
+ tag_out, seckey_out->seckey,
+ sizeof(seckey_out->seckey));
+ if (len != sizeof(seckey_out->seckey))
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
+ * Return 0 on success, -1 on failure.
+ */
+int
+ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
+ const char *filename,
+ const char *tag)
+{
+ return crypto_write_tagged_contents_to_file(filename,
+ "ed25519v1-public",
+ tag,
+ pubkey->pubkey,
+ sizeof(pubkey->pubkey));
+}
+
+/**
+ * Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
+ * Return 0 on success, -1 on failure.
+ */
+int
+ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
+ char **tag_out,
+ const char *filename)
+{
+ ssize_t len;
+
+ len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-public",
+ tag_out, pubkey_out->pubkey,
+ sizeof(pubkey_out->pubkey));
+ if (len != sizeof(pubkey_out->pubkey))
+ return -1;
+
+ return 0;
+}
+
diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h
new file mode 100644
index 0000000000..13b05c7c1e
--- /dev/null
+++ b/src/common/crypto_ed25519.h
@@ -0,0 +1,116 @@
+/* Copyright (c) 2012-2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_CRYPTO_ED25519_H
+#define TOR_CRYPTO_ED25519_H
+
+#include "testsupport.h"
+#include "torint.h"
+
+#define ED25519_PUBKEY_LEN 32
+#define ED25519_SECKEY_LEN 64
+#define ED25519_SECKEY_SEED_LEN 32
+#define ED25519_SIG_LEN 64
+
+/** An Ed25519 signature. */
+typedef struct {
+ uint8_t sig[ED25519_SIG_LEN];
+} ed25519_signature_t;
+
+/** An Ed25519 public key */
+typedef struct {
+ uint8_t pubkey[ED25519_PUBKEY_LEN];
+} ed25519_public_key_t;
+
+/** An Ed25519 secret key */
+typedef struct {
+ /** Note that we store secret keys in an expanded format that doesn't match
+ * the format from standard ed25519. Ed25519 stores a 32-byte value k and
+ * expands it into a 64-byte H(k), using the first 32 bytes for a multiplier
+ * of the base point, and second 32 bytes as an input to a hash function
+ * for deriving r. But because we implement key blinding, we need to store
+ * keys in the 64-byte expanded form. */
+ uint8_t seckey[ED25519_SECKEY_LEN];
+} ed25519_secret_key_t;
+
+/** An Ed25519 keypair. */
+typedef struct {
+ ed25519_public_key_t pubkey;
+ ed25519_secret_key_t seckey;
+} ed25519_keypair_t;
+
+#ifdef CURVE25519_ENABLED
+int ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
+ int extra_strong);
+int ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out,
+ const uint8_t *seed);
+
+int ed25519_public_key_generate(ed25519_public_key_t *pubkey_out,
+ const ed25519_secret_key_t *seckey);
+int ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong);
+int ed25519_sign(ed25519_signature_t *signature_out,
+ const uint8_t *msg, size_t len,
+ const ed25519_keypair_t *key);
+int ed25519_checksig(const ed25519_signature_t *signature,
+ const uint8_t *msg, size_t len,
+ const ed25519_public_key_t *pubkey);
+
+/**
+ * A collection of information necessary to check an Ed25519 signature. Used
+ * for batch verification.
+ */
+typedef struct {
+ /** The public key that supposedly generated the signature. */
+ ed25519_public_key_t *pubkey;
+ /** The signature to check. */
+ ed25519_signature_t signature;
+ /** The message that the signature is supposed to have been applied to. */
+ const uint8_t *msg;
+ /** The length of the message. */
+ size_t len;
+} ed25519_checkable_t;
+
+int ed25519_checksig_batch(int *okay_out,
+ const ed25519_checkable_t *checkable,
+ int n_checkable);
+
+int ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out,
+ int *signbit_out,
+ const curve25519_keypair_t *inp);
+
+int ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey,
+ const curve25519_public_key_t *pubkey_in,
+ int signbit);
+int ed25519_keypair_blind(ed25519_keypair_t *out,
+ const ed25519_keypair_t *inp,
+ const uint8_t *param);
+int ed25519_public_blind(ed25519_public_key_t *out,
+ const ed25519_public_key_t *inp,
+ const uint8_t *param);
+
+#endif
+
+#define ED25519_BASE64_LEN 43
+
+int ed25519_public_from_base64(ed25519_public_key_t *pkey,
+ const char *input);
+int ed25519_public_to_base64(char *output,
+ const ed25519_public_key_t *pkey);
+
+/* XXXX read encrypted, write encrypted. */
+
+int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
+ const char *filename,
+ const char *tag);
+int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
+ char **tag_out,
+ const char *filename);
+int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
+ const char *filename,
+ const char *tag);
+int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
+ char **tag_out,
+ const char *filename);
+
+#endif
+
diff --git a/src/common/crypto_format.c b/src/common/crypto_format.c
index be669c8d2b..a9f104cab2 100644
--- a/src/common/crypto_format.c
+++ b/src/common/crypto_format.c
@@ -9,6 +9,7 @@
#endif
#include "crypto.h"
#include "crypto_curve25519.h"
+#include "crypto_ed25519.h"
#include "util.h"
#include "torlog.h"
@@ -43,3 +44,24 @@ curve25519_public_from_base64(curve25519_public_key_t *pkey,
}
}
+/** Try to decode the string <b>input</b> into an ed25519 public key. On
+ * success, store the value in <b>pkey</b> and return 0. Otherwise return
+ * -1. */
+int
+ed25519_public_from_base64(ed25519_public_key_t *pkey,
+ const char *input)
+{
+ return digest256_from_base64((char*)pkey->pubkey, input);
+}
+
+/** Encode the public key <b>pkey</b> into the buffer at <b>output</b>,
+ * which must have space for ED25519_BASE64_LEN bytes of encoded key,
+ * plus one byte for a terminating NUL. Return 0 on success, -1 on failure.
+ */
+int
+ed25519_public_to_base64(char *output,
+ const ed25519_public_key_t *pkey)
+{
+ return digest256_to_base64(output, (const char *)pkey->pubkey);
+}
+
diff --git a/src/common/crypto_pwbox.c b/src/common/crypto_pwbox.c
new file mode 100644
index 0000000000..91659db2bc
--- /dev/null
+++ b/src/common/crypto_pwbox.c
@@ -0,0 +1,187 @@
+
+#include "crypto.h"
+#include "crypto_s2k.h"
+#include "crypto_pwbox.h"
+#include "di_ops.h"
+#include "util.h"
+#include "pwbox.h"
+
+/* 8 bytes "TORBOX00"
+ 1 byte: header len (H)
+ H bytes: header, denoting secret key algorithm.
+ 16 bytes: IV
+ Round up to multiple of 128 bytes, then encrypt:
+ 4 bytes: data len
+ data
+ zeros
+ 32 bytes: HMAC-SHA256 of all previous bytes.
+*/
+
+#define MAX_OVERHEAD (S2K_MAXLEN + 8 + 1 + 32 + CIPHER_IV_LEN)
+
+/**
+ * Make an authenticated passphrase-encrypted blob to encode the
+ * <b>input_len</b> bytes in <b>input</b> using the passphrase
+ * <b>secret</b> of <b>secret_len</b> bytes. Allocate a new chunk of memory
+ * to hold the encrypted data, and store a pointer to that memory in
+ * *<b>out</b>, and its size in <b>outlen_out</b>. Use <b>s2k_flags</b> as an
+ * argument to the passphrase-hashing function.
+ */
+int
+crypto_pwbox(uint8_t **out, size_t *outlen_out,
+ const uint8_t *input, size_t input_len,
+ const char *secret, size_t secret_len,
+ unsigned s2k_flags)
+{
+ uint8_t *result = NULL, *encrypted_portion;
+ size_t encrypted_len = 128 * CEIL_DIV(input_len+4, 128);
+ ssize_t result_len;
+ int spec_len;
+ uint8_t keys[CIPHER_KEY_LEN + DIGEST256_LEN];
+ pwbox_encoded_t *enc = NULL;
+ ssize_t enc_len;
+
+ crypto_cipher_t *cipher;
+ int rv;
+
+ enc = pwbox_encoded_new();
+
+ pwbox_encoded_setlen_skey_header(enc, S2K_MAXLEN);
+
+ spec_len = secret_to_key_make_specifier(
+ pwbox_encoded_getarray_skey_header(enc),
+ S2K_MAXLEN,
+ s2k_flags);
+ if (spec_len < 0 || spec_len > S2K_MAXLEN)
+ goto err;
+ pwbox_encoded_setlen_skey_header(enc, spec_len);
+ enc->header_len = spec_len;
+
+ crypto_rand((char*)enc->iv, sizeof(enc->iv));
+
+ pwbox_encoded_setlen_data(enc, encrypted_len);
+ encrypted_portion = pwbox_encoded_getarray_data(enc);
+
+ set_uint32(encrypted_portion, htonl(input_len));
+ memcpy(encrypted_portion+4, input, input_len);
+
+ /* Now that all the data is in position, derive some keys, encrypt, and
+ * digest */
+ if (secret_to_key_derivekey(keys, sizeof(keys),
+ pwbox_encoded_getarray_skey_header(enc),
+ spec_len,
+ secret, secret_len) < 0)
+ goto err;
+
+ cipher = crypto_cipher_new_with_iv((char*)keys, (char*)enc->iv);
+ crypto_cipher_crypt_inplace(cipher, (char*)encrypted_portion, encrypted_len);
+ crypto_cipher_free(cipher);
+
+ result_len = pwbox_encoded_encoded_len(enc);
+ if (result_len < 0)
+ goto err;
+ result = tor_malloc(result_len);
+ enc_len = pwbox_encoded_encode(result, result_len, enc);
+ if (enc_len < 0)
+ goto err;
+ tor_assert(enc_len == result_len);
+
+ crypto_hmac_sha256((char*) result + result_len - 32,
+ (const char*)keys + CIPHER_KEY_LEN,
+ DIGEST256_LEN,
+ (const char*)result,
+ result_len - 32);
+
+ *out = result;
+ *outlen_out = result_len;
+ rv = 0;
+ goto out;
+
+ err:
+ tor_free(result);
+ rv = -1;
+
+ out:
+ pwbox_encoded_free(enc);
+ memwipe(keys, 0, sizeof(keys));
+ return rv;
+}
+
+/**
+ * Try to decrypt the passphrase-encrypted blob of <b>input_len</b> bytes in
+ * <b>input</b> using the passphrase <b>secret</b> of <b>secret_len</b> bytes.
+ * On success, return 0 and allocate a new chunk of memory to hold the
+ * decrypted data, and store a pointer to that memory in *<b>out</b>, and its
+ * size in <b>outlen_out</b>. On failure, return UNPWBOX_BAD_SECRET if
+ * the passphrase might have been wrong, and UNPWBOX_CORRUPT if the object is
+ * definitely corrupt.
+ */
+int
+crypto_unpwbox(uint8_t **out, size_t *outlen_out,
+ const uint8_t *inp, size_t input_len,
+ const char *secret, size_t secret_len)
+{
+ uint8_t *result = NULL;
+ const uint8_t *encrypted;
+ uint8_t keys[CIPHER_KEY_LEN + DIGEST256_LEN];
+ uint8_t hmac[DIGEST256_LEN];
+ uint32_t result_len;
+ size_t encrypted_len;
+ crypto_cipher_t *cipher = NULL;
+ int rv = UNPWBOX_CORRUPTED;
+ ssize_t got_len;
+
+ pwbox_encoded_t *enc = NULL;
+
+ got_len = pwbox_encoded_parse(&enc, inp, input_len);
+ if (got_len < 0 || (size_t)got_len != input_len)
+ goto err;
+
+ /* Now derive the keys and check the hmac. */
+ if (secret_to_key_derivekey(keys, sizeof(keys),
+ pwbox_encoded_getarray_skey_header(enc),
+ pwbox_encoded_getlen_skey_header(enc),
+ secret, secret_len) < 0)
+ goto err;
+
+ crypto_hmac_sha256((char *)hmac,
+ (const char*)keys + CIPHER_KEY_LEN, DIGEST256_LEN,
+ (const char*)inp, input_len - DIGEST256_LEN);
+
+ if (tor_memneq(hmac, enc->hmac, DIGEST256_LEN)) {
+ rv = UNPWBOX_BAD_SECRET;
+ goto err;
+ }
+
+ /* How long is the plaintext? */
+ encrypted = pwbox_encoded_getarray_data(enc);
+ encrypted_len = pwbox_encoded_getlen_data(enc);
+ if (encrypted_len < 4)
+ goto err;
+
+ cipher = crypto_cipher_new_with_iv((char*)keys, (char*)enc->iv);
+ crypto_cipher_decrypt(cipher, (char*)&result_len, (char*)encrypted, 4);
+ result_len = ntohl(result_len);
+ if (encrypted_len < result_len + 4)
+ goto err;
+
+ /* Allocate a buffer and decrypt */
+ result = tor_malloc_zero(result_len);
+ crypto_cipher_decrypt(cipher, (char*)result, (char*)encrypted+4, result_len);
+
+ *out = result;
+ *outlen_out = result_len;
+
+ rv = UNPWBOX_OKAY;
+ goto out;
+
+ err:
+ tor_free(result);
+
+ out:
+ crypto_cipher_free(cipher);
+ pwbox_encoded_free(enc);
+ memwipe(keys, 0, sizeof(keys));
+ return rv;
+}
+
diff --git a/src/common/crypto_pwbox.h b/src/common/crypto_pwbox.h
new file mode 100644
index 0000000000..aadd477078
--- /dev/null
+++ b/src/common/crypto_pwbox.h
@@ -0,0 +1,20 @@
+#ifndef CRYPTO_PWBOX_H_INCLUDED_
+#define CRYPTO_PWBOX_H_INCLUDED_
+
+#include "torint.h"
+
+#define UNPWBOX_OKAY 0
+#define UNPWBOX_BAD_SECRET -1
+#define UNPWBOX_CORRUPTED -2
+
+int crypto_pwbox(uint8_t **out, size_t *outlen_out,
+ const uint8_t *inp, size_t input_len,
+ const char *secret, size_t secret_len,
+ unsigned s2k_flags);
+
+int crypto_unpwbox(uint8_t **out, size_t *outlen_out,
+ const uint8_t *inp, size_t input_len,
+ const char *secret, size_t secret_len);
+
+#endif
+
diff --git a/src/common/crypto_s2k.c b/src/common/crypto_s2k.c
new file mode 100644
index 0000000000..aef8436ad9
--- /dev/null
+++ b/src/common/crypto_s2k.c
@@ -0,0 +1,460 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define CRYPTO_S2K_PRIVATE
+
+#include "crypto.h"
+#include "util.h"
+#include "compat.h"
+#include "crypto_s2k.h"
+
+#include <openssl/evp.h>
+
+#ifdef HAVE_LIBSCRYPT_H
+#define HAVE_SCRYPT
+#include <libscrypt.h>
+#endif
+
+/* Encoded secrets take the form:
+
+ u8 type;
+ u8 salt_and_parameters[depends on type];
+ u8 key[depends on type];
+
+ As a special case, if the encoded secret is exactly 29 bytes long,
+ type 0 is understood.
+
+ Recognized types are:
+ 00 -- RFC2440. salt_and_parameters is 9 bytes. key is 20 bytes.
+ salt_and_parameters is 8 bytes random salt,
+ 1 byte iteration info.
+ 01 -- PKBDF2_SHA1. salt_and_parameters is 17 bytes. key is 20 bytes.
+ salt_and_parameters is 16 bytes random salt,
+ 1 byte iteration info.
+ 02 -- SCRYPT_SALSA208_SHA256. salt_and_parameters is 18 bytes. key is
+ 32 bytes.
+ salt_and_parameters is 18 bytes random salt, 2 bytes iteration
+ info.
+*/
+
+#define S2K_TYPE_RFC2440 0
+#define S2K_TYPE_PBKDF2 1
+#define S2K_TYPE_SCRYPT 2
+
+#define PBKDF2_SPEC_LEN 17
+#define PBKDF2_KEY_LEN 20
+
+#define SCRYPT_SPEC_LEN 18
+#define SCRYPT_KEY_LEN 32
+
+/** Given an algorithm ID (one of S2K_TYPE_*), return the length of the
+ * specifier part of it, without the prefix type byte. */
+static int
+secret_to_key_spec_len(uint8_t type)
+{
+ switch (type) {
+ case S2K_TYPE_RFC2440:
+ return S2K_RFC2440_SPECIFIER_LEN;
+ case S2K_TYPE_PBKDF2:
+ return PBKDF2_SPEC_LEN;
+ case S2K_TYPE_SCRYPT:
+ return SCRYPT_SPEC_LEN;
+ default:
+ return -1;
+ }
+}
+
+/** Given an algorithm ID (one of S2K_TYPE_*), return the length of the
+ * its preferred output. */
+static int
+secret_to_key_key_len(uint8_t type)
+{
+ switch (type) {
+ case S2K_TYPE_RFC2440:
+ return DIGEST_LEN;
+ case S2K_TYPE_PBKDF2:
+ return DIGEST_LEN;
+ case S2K_TYPE_SCRYPT:
+ return DIGEST256_LEN;
+ default:
+ return -1;
+ }
+}
+
+/** Given a specifier in <b>spec_and_key</b> of length
+ * <b>spec_and_key_len</b>, along with its prefix algorithm ID byte, and along
+ * with a key if <b>key_included</b> is true, check whether the whole
+ * specifier-and-key is of valid length, and return the algorithm type if it
+ * is. Set *<b>legacy_out</b> to 1 iff this is a legacy password hash or
+ * legacy specifier. Return an error code on failure.
+ */
+static int
+secret_to_key_get_type(const uint8_t *spec_and_key, size_t spec_and_key_len,
+ int key_included, int *legacy_out)
+{
+ size_t legacy_len = S2K_RFC2440_SPECIFIER_LEN;
+ uint8_t type;
+ int total_len;
+
+ if (key_included)
+ legacy_len += DIGEST_LEN;
+
+ if (spec_and_key_len == legacy_len) {
+ *legacy_out = 1;
+ return S2K_TYPE_RFC2440;
+ }
+
+ *legacy_out = 0;
+ if (spec_and_key_len == 0)
+ return S2K_BAD_LEN;
+
+ type = spec_and_key[0];
+ total_len = secret_to_key_spec_len(type);
+ if (total_len < 0)
+ return S2K_BAD_ALGORITHM;
+ if (key_included) {
+ int keylen = secret_to_key_key_len(type);
+ if (keylen < 0)
+ return S2K_BAD_ALGORITHM;
+ total_len += keylen;
+ }
+
+ if ((size_t)total_len + 1 == spec_and_key_len)
+ return type;
+ else
+ return S2K_BAD_LEN;
+}
+
+/**
+ * Write a new random s2k specifier of type <b>type</b>, without prefixing
+ * type byte, to <b>spec_out</b>, which must have enough room. May adjust
+ * parameter choice based on <b>flags</b>.
+ */
+static int
+make_specifier(uint8_t *spec_out, uint8_t type, unsigned flags)
+{
+ int speclen = secret_to_key_spec_len(type);
+ if (speclen < 0)
+ return S2K_BAD_ALGORITHM;
+
+ crypto_rand((char*)spec_out, speclen);
+ switch (type) {
+ case S2K_TYPE_RFC2440:
+ /* Hash 64 k of data. */
+ spec_out[S2K_RFC2440_SPECIFIER_LEN-1] = 96;
+ break;
+ case S2K_TYPE_PBKDF2:
+ /* 131 K iterations */
+ spec_out[PBKDF2_SPEC_LEN-1] = 17;
+ break;
+ case S2K_TYPE_SCRYPT:
+ if (flags & S2K_FLAG_LOW_MEM) {
+ /* N = 1<<12 */
+ spec_out[SCRYPT_SPEC_LEN-2] = 12;
+ } else {
+ /* N = 1<<15 */
+ spec_out[SCRYPT_SPEC_LEN-2] = 15;
+ }
+ /* r = 8; p = 2. */
+ spec_out[SCRYPT_SPEC_LEN-1] = (3u << 4) | (1u << 0);
+ break;
+ default:
+ tor_fragile_assert();
+ return S2K_BAD_ALGORITHM;
+ }
+
+ return speclen;
+}
+
+/** Implement RFC2440-style iterated-salted S2K conversion: convert the
+ * <b>secret_len</b>-byte <b>secret</b> into a <b>key_out_len</b> byte
+ * <b>key_out</b>. As in RFC2440, the first 8 bytes of s2k_specifier
+ * are a salt; the 9th byte describes how much iteration to do.
+ * If <b>key_out_len</b> &gt; DIGEST_LEN, use HDKF to expand the result.
+ */
+void
+secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret,
+ size_t secret_len, const char *s2k_specifier)
+{
+ crypto_digest_t *d;
+ uint8_t c;
+ size_t count, tmplen;
+ char *tmp;
+ uint8_t buf[DIGEST_LEN];
+ tor_assert(key_out_len < SIZE_T_CEILING);
+
+#define EXPBIAS 6
+ c = s2k_specifier[8];
+ count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
+#undef EXPBIAS
+
+ d = crypto_digest_new();
+ tmplen = 8+secret_len;
+ tmp = tor_malloc(tmplen);
+ memcpy(tmp,s2k_specifier,8);
+ memcpy(tmp+8,secret,secret_len);
+ secret_len += 8;
+ while (count) {
+ if (count >= secret_len) {
+ crypto_digest_add_bytes(d, tmp, secret_len);
+ count -= secret_len;
+ } else {
+ crypto_digest_add_bytes(d, tmp, count);
+ count = 0;
+ }
+ }
+ crypto_digest_get_digest(d, (char*)buf, sizeof(buf));
+
+ if (key_out_len <= sizeof(buf)) {
+ memcpy(key_out, buf, key_out_len);
+ } else {
+ crypto_expand_key_material_rfc5869_sha256(buf, DIGEST_LEN,
+ (const uint8_t*)s2k_specifier, 8,
+ (const uint8_t*)"EXPAND", 6,
+ (uint8_t*)key_out, key_out_len);
+ }
+ memwipe(tmp, 0, tmplen);
+ memwipe(buf, 0, sizeof(buf));
+ tor_free(tmp);
+ crypto_digest_free(d);
+}
+
+/**
+ * Helper: given a valid specifier without prefix type byte in <b>spec</b>,
+ * whose length must be correct, and given a secret passphrase <b>secret</b>
+ * of length <b>secret_len</b>, compute the key and store it into
+ * <b>key_out</b>, which must have enough room for secret_to_key_key_len(type)
+ * bytes. Return the number of bytes written on success and an error code
+ * on failure.
+ */
+STATIC int
+secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len,
+ const uint8_t *spec, size_t spec_len,
+ const char *secret, size_t secret_len,
+ int type)
+{
+ int rv;
+ if (key_out_len > INT_MAX)
+ return S2K_BAD_LEN;
+
+ switch (type) {
+ case S2K_TYPE_RFC2440:
+ secret_to_key_rfc2440((char*)key_out, key_out_len, secret, secret_len,
+ (const char*)spec);
+ return (int)key_out_len;
+
+ case S2K_TYPE_PBKDF2: {
+ uint8_t log_iters;
+ if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX)
+ return S2K_BAD_LEN;
+ log_iters = spec[spec_len-1];
+ if (log_iters > 31)
+ return S2K_BAD_PARAMS;
+ rv = PKCS5_PBKDF2_HMAC_SHA1(secret, (int)secret_len,
+ spec, (int)spec_len-1,
+ (1<<log_iters),
+ (int)key_out_len, key_out);
+ if (rv < 0)
+ return S2K_FAILED;
+ return (int)key_out_len;
+ }
+
+ case S2K_TYPE_SCRYPT: {
+#ifdef HAVE_SCRYPT
+ uint8_t log_N, log_r, log_p;
+ uint64_t N;
+ uint32_t r, p;
+ if (spec_len < 2)
+ return S2K_BAD_LEN;
+ log_N = spec[spec_len-2];
+ log_r = (spec[spec_len-1]) >> 4;
+ log_p = (spec[spec_len-1]) & 15;
+ if (log_N > 63)
+ return S2K_BAD_PARAMS;
+ N = ((uint64_t)1) << log_N;
+ r = 1u << log_r;
+ p = 1u << log_p;
+ rv = libscrypt_scrypt((const uint8_t*)secret, secret_len,
+ spec, spec_len-2, N, r, p, key_out, key_out_len);
+ if (rv != 0)
+ return S2K_FAILED;
+ return (int)key_out_len;
+#else
+ return S2K_NO_SCRYPT_SUPPORT;
+#endif
+ }
+ default:
+ return S2K_BAD_ALGORITHM;
+ }
+}
+
+/**
+ * Given a specifier previously constructed with secret_to_key_make_specifier
+ * in <b>spec</b> of length <b>spec_len</b>, and a secret password in
+ * <b>secret</b> of length <b>secret_len</b>, generate <b>key_out_len</b>
+ * bytes of cryptographic material in <b>key_out</b>. The native output of
+ * the secret-to-key function will be truncated if key_out_len is short, and
+ * expanded with HKDF if key_out_len is long. Returns S2K_OKAY on success,
+ * and an error code on failure.
+ */
+int
+secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len,
+ const uint8_t *spec, size_t spec_len,
+ const char *secret, size_t secret_len)
+{
+ int legacy_format = 0;
+ int type = secret_to_key_get_type(spec, spec_len, 0, &legacy_format);
+ int r;
+
+ if (type < 0)
+ return type;
+#ifndef HAVE_SCRYPT
+ if (type == S2K_TYPE_SCRYPT)
+ return S2K_NO_SCRYPT_SUPPORT;
+ #endif
+
+ if (! legacy_format) {
+ ++spec;
+ --spec_len;
+ }
+
+ r = secret_to_key_compute_key(key_out, key_out_len, spec, spec_len,
+ secret, secret_len, type);
+ if (r < 0)
+ return r;
+ else
+ return S2K_OKAY;
+}
+
+/**
+ * Construct a new s2k algorithm specifier and salt in <b>buf</b>, according
+ * to the bitwise-or of some S2K_FLAG_* options in <b>flags</b>. Up to
+ * <b>buf_len</b> bytes of storage may be used in <b>buf</b>. Return the
+ * number of bytes used on success and an error code on failure.
+ */
+int
+secret_to_key_make_specifier(uint8_t *buf, size_t buf_len, unsigned flags)
+{
+ int rv;
+ int spec_len;
+#ifdef HAVE_SCRYPT
+ uint8_t type = S2K_TYPE_SCRYPT;
+#else
+ uint8_t type = S2K_TYPE_RFC2440;
+#endif
+
+ if (flags & S2K_FLAG_NO_SCRYPT)
+ type = S2K_TYPE_RFC2440;
+ if (flags & S2K_FLAG_USE_PBKDF2)
+ type = S2K_TYPE_PBKDF2;
+
+ spec_len = secret_to_key_spec_len(type);
+
+ if ((int)buf_len < spec_len + 1)
+ return S2K_TRUNCATED;
+
+ buf[0] = type;
+ rv = make_specifier(buf+1, type, flags);
+ if (rv < 0)
+ return rv;
+ else
+ return rv + 1;
+}
+
+/**
+ * Hash a passphrase from <b>secret</b> of length <b>secret_len</b>, according
+ * to the bitwise-or of some S2K_FLAG_* options in <b>flags</b>, and store the
+ * hash along with salt and hashing parameters into <b>buf</b>. Up to
+ * <b>buf_len</b> bytes of storage may be used in <b>buf</b>. Set
+ * *<b>len_out</b> to the number of bytes used and return S2K_OKAY on success;
+ * and return an error code on failure.
+ */
+int
+secret_to_key_new(uint8_t *buf,
+ size_t buf_len,
+ size_t *len_out,
+ const char *secret, size_t secret_len,
+ unsigned flags)
+{
+ int key_len;
+ int spec_len;
+ int type;
+ int rv;
+
+ spec_len = secret_to_key_make_specifier(buf, buf_len, flags);
+
+ if (spec_len < 0)
+ return spec_len;
+
+ type = buf[0];
+ key_len = secret_to_key_key_len(type);
+
+ if (key_len < 0)
+ return key_len;
+
+ if ((int)buf_len < key_len + spec_len)
+ return S2K_TRUNCATED;
+
+ rv = secret_to_key_compute_key(buf + spec_len, key_len,
+ buf + 1, spec_len-1,
+ secret, secret_len, type);
+ if (rv < 0)
+ return rv;
+
+ *len_out = spec_len + key_len;
+
+ return S2K_OKAY;
+}
+
+/**
+ * Given a hashed passphrase in <b>spec_and_key</b> of length
+ * <b>spec_and_key_len</b> as generated by secret_to_key_new(), verify whether
+ * it is a hash of the passphrase <b>secret</b> of length <b>secret_len</b>.
+ * Return S2K_OKAY on a match, S2K_BAD_SECRET on a well-formed hash that
+ * doesn't match this secret, and another error code on other errors.
+ */
+int
+secret_to_key_check(const uint8_t *spec_and_key, size_t spec_and_key_len,
+ const char *secret, size_t secret_len)
+{
+ int is_legacy = 0;
+ int type = secret_to_key_get_type(spec_and_key, spec_and_key_len,
+ 1, &is_legacy);
+ uint8_t buf[32];
+ int spec_len;
+ int key_len;
+ int rv;
+
+ if (type < 0)
+ return type;
+
+ if (! is_legacy) {
+ spec_and_key++;
+ spec_and_key_len--;
+ }
+
+ spec_len = secret_to_key_spec_len(type);
+ key_len = secret_to_key_key_len(type);
+ tor_assert(spec_len > 0);
+ tor_assert(key_len > 0);
+ tor_assert(key_len <= (int) sizeof(buf));
+ tor_assert((int)spec_and_key_len == spec_len + key_len);
+ rv = secret_to_key_compute_key(buf, key_len,
+ spec_and_key, spec_len,
+ secret, secret_len, type);
+ if (rv < 0)
+ goto done;
+
+ if (tor_memeq(buf, spec_and_key + spec_len, key_len))
+ rv = S2K_OKAY;
+ else
+ rv = S2K_BAD_SECRET;
+
+ done:
+ memwipe(buf, 0, sizeof(buf));
+ return rv;
+}
+
diff --git a/src/common/crypto_s2k.h b/src/common/crypto_s2k.h
new file mode 100644
index 0000000000..3693a430e7
--- /dev/null
+++ b/src/common/crypto_s2k.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_CRYPTO_S2K_H_INCLUDED
+#define TOR_CRYPTO_S2K_H_INCLUDED
+
+#include <stdio.h>
+#include "torint.h"
+
+/** Length of RFC2440-style S2K specifier: the first 8 bytes are a salt, the
+ * 9th describes how much iteration to do. */
+#define S2K_RFC2440_SPECIFIER_LEN 9
+void secret_to_key_rfc2440(
+ char *key_out, size_t key_out_len, const char *secret,
+ size_t secret_len, const char *s2k_specifier);
+
+/** Flag for secret-to-key function: do not use scrypt. */
+#define S2K_FLAG_NO_SCRYPT (1u<<0)
+/** Flag for secret-to-key functions: if using a memory-tuned s2k function,
+ * assume that we have limited memory. */
+#define S2K_FLAG_LOW_MEM (1u<<1)
+/** Flag for secret-to-key functions: force use of pbkdf2. Without this, we
+ * default to scrypt, then RFC2440. */
+#define S2K_FLAG_USE_PBKDF2 (1u<<2)
+
+/** Maximum possible output length from secret_to_key_new. */
+#define S2K_MAXLEN 64
+
+/** Error code from secret-to-key functions: all is well */
+#define S2K_OKAY 0
+/** Error code from secret-to-key functions: generic failure */
+#define S2K_FAILED -1
+/** Error code from secret-to-key functions: provided secret didn't match */
+#define S2K_BAD_SECRET -2
+/** Error code from secret-to-key functions: didn't recognize the algorithm */
+#define S2K_BAD_ALGORITHM -3
+/** Error code from secret-to-key functions: specifier wasn't valid */
+#define S2K_BAD_PARAMS -4
+/** Error code from secret-to-key functions: compiled without scrypt */
+#define S2K_NO_SCRYPT_SUPPORT -5
+/** Error code from secret-to-key functions: not enough space to write output.
+ */
+#define S2K_TRUNCATED -6
+/** Error code from secret-to-key functions: Wrong length for specifier. */
+#define S2K_BAD_LEN -7
+
+int secret_to_key_new(uint8_t *buf,
+ size_t buf_len,
+ size_t *len_out,
+ const char *secret, size_t secret_len,
+ unsigned flags);
+
+int secret_to_key_make_specifier(uint8_t *buf, size_t buf_len, unsigned flags);
+
+int secret_to_key_check(const uint8_t *spec_and_key, size_t spec_and_key_len,
+ const char *secret, size_t secret_len);
+
+int secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len,
+ const uint8_t *spec, size_t spec_len,
+ const char *secret, size_t secret_len);
+
+#ifdef CRYPTO_S2K_PRIVATE
+STATIC int secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len,
+ const uint8_t *spec, size_t spec_len,
+ const char *secret, size_t secret_len,
+ int type);
+#endif
+
+#endif
+
diff --git a/src/common/di_ops.c b/src/common/di_ops.c
index 14a1443400..a8bfd02532 100644
--- a/src/common/di_ops.c
+++ b/src/common/di_ops.c
@@ -130,6 +130,7 @@ tor_memeq(const void *a, const void *b, size_t sz)
* 1 & ((any_difference - 1) >> 8) == 0
*/
+ /*coverity[overflow]*/
return 1 & ((any_difference - 1) >> 8);
}
@@ -217,6 +218,7 @@ safe_mem_is_zero(const void *mem, size_t sz)
total |= *ptr++;
}
+ /*coverity[overflow]*/
return 1 & ((total - 1) >> 8);
}
diff --git a/src/common/include.am b/src/common/include.am
index 68e0110c26..5c000e86f3 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -16,7 +16,7 @@ EXTRA_DIST+= \
src/common/Makefile.nmake
#CFLAGS = -Wall -Wpointer-arith -O2
-AM_CPPFLAGS += -I$(srcdir)/src/common -Isrc/common
+AM_CPPFLAGS += -I$(srcdir)/src/common -Isrc/common -I$(srcdir)/src/ext/trunnel -I$(srcdir)/src/trunnel
if USE_OPENBSD_MALLOC
libor_extra_source=src/ext/OpenBSD_malloc_Linux.c
@@ -52,8 +52,12 @@ LIBDONNA=
endif
endif
+LIBDONNA += $(LIBED25519_REF10)
+
if CURVE25519_ENABLED
-libcrypto_extra_source=src/common/crypto_curve25519.c
+libcrypto_extra_source = \
+ src/common/crypto_curve25519.c \
+ src/common/crypto_ed25519.c
endif
LIBOR_A_SOURCES = \
@@ -69,15 +73,19 @@ LIBOR_A_SOURCES = \
src/common/util_process.c \
src/common/sandbox.c \
src/ext/csiphash.c \
+ src/ext/trunnel/trunnel.c \
$(libor_extra_source) \
$(libor_mempool_source)
LIBOR_CRYPTO_A_SOURCES = \
src/common/aes.c \
src/common/crypto.c \
+ src/common/crypto_pwbox.c \
+ src/common/crypto_s2k.c \
src/common/crypto_format.c \
src/common/torgzip.c \
src/common/tortls.c \
+ src/trunnel/pwbox.c \
$(libcrypto_extra_source)
LIBOR_EVENT_A_SOURCES = \
@@ -110,6 +118,9 @@ COMMONHEADERS = \
src/common/container.h \
src/common/crypto.h \
src/common/crypto_curve25519.h \
+ src/common/crypto_ed25519.h \
+ src/common/crypto_pwbox.h \
+ src/common/crypto_s2k.h \
src/common/di_ops.h \
src/common/memarea.h \
src/common/linux_syscalls.inc \
diff --git a/src/common/log.c b/src/common/log.c
index 517fa4faaa..2e51e5c578 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -1010,12 +1010,16 @@ mark_logs_temp(void)
* logfile fails, -1 is returned and errno is set appropriately (by open(2)).
*/
int
-add_file_log(const log_severity_list_t *severity, const char *filename)
+add_file_log(const log_severity_list_t *severity, const char *filename,
+ const int truncate)
{
int fd;
logfile_t *lf;
- fd = tor_open_cloexec(filename, O_WRONLY|O_CREAT|O_APPEND, 0644);
+ int open_flags = O_WRONLY|O_CREAT;
+ open_flags |= truncate ? O_TRUNC : O_APPEND;
+
+ fd = tor_open_cloexec(filename, open_flags, 0644);
if (fd<0)
return -1;
if (tor_fd_seekend(fd)<0) {
@@ -1297,3 +1301,15 @@ switch_logs_debug(void)
UNLOCK_LOGS();
}
+/** Truncate all the log files. */
+void
+truncate_logs(void)
+{
+ logfile_t *lf;
+ for (lf = logfiles; lf; lf = lf->next) {
+ if (lf->fd >= 0) {
+ tor_ftruncate(lf->fd);
+ }
+ }
+}
+
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index dbbaa59d7c..36022c921c 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -98,6 +98,8 @@ static sandbox_cfg_t *filter_dynamic = NULL;
#undef SCMP_CMP
#define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0})
+#define SCMP_CMP_STR(a,b,c) \
+ ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0})
#define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)})
/* We use a wrapper here because these masked comparisons seem to be pretty
* verbose. Also, it's important to cast to scmp_datum_t before negating the
@@ -252,7 +254,7 @@ sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(execve)) {
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value));
+ SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add execve syscall, received "
"libseccomp error %d", rc);
@@ -389,7 +391,7 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(open)) {
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value));
+ SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
"libseccomp error %d", rc);
@@ -444,8 +446,8 @@ sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
param->syscall == SCMP_SYS(rename)) {
rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value),
- SCMP_CMP(1, SCMP_CMP_EQ, param->value2));
+ SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received "
"libseccomp error %d", rc);
@@ -475,7 +477,7 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
== SCMP_SYS(openat)) {
rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
- SCMP_CMP(1, SCMP_CMP_EQ, param->value),
+ SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value),
SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
O_CLOEXEC));
if (rc != 0) {
@@ -884,7 +886,7 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
|| param->syscall == SCMP_SYS(stat64))) {
rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64),
- SCMP_CMP(0, SCMP_CMP_EQ, param->value));
+ SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
"libseccomp error %d", rc);
@@ -967,7 +969,7 @@ static int
prot_strings_helper(strmap_t *locations,
char **pr_mem_next_p,
size_t *pr_mem_left_p,
- intptr_t *value_p)
+ char **value_p)
{
char *param_val;
size_t param_size;
@@ -983,7 +985,7 @@ prot_strings_helper(strmap_t *locations,
if (location) {
// We already interned this string.
tor_free(param_val);
- *value_p = (intptr_t) location;
+ *value_p = location;
return 0;
} else if (*pr_mem_left_p >= param_size) {
// copy to protected
@@ -992,7 +994,7 @@ prot_strings_helper(strmap_t *locations,
// re-point el parameter to protected
tor_free(param_val);
- *value_p = (intptr_t) location;
+ *value_p = location;
strmap_set(locations, location, location); /* good real estate advice */
@@ -1074,7 +1076,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
if (ret) {
log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!");
- return ret;
+ goto out;
}
// no munmap of the protected base address
@@ -1082,7 +1084,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base));
if (ret) {
log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!");
- return ret;
+ goto out;
}
/*
@@ -1101,7 +1103,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
if (ret) {
log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!");
- return ret;
+ goto out;
}
ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect),
@@ -1111,7 +1113,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE));
if (ret) {
log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!");
- return ret;
+ goto out;
}
out:
@@ -1126,7 +1128,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg)
* point.
*/
static sandbox_cfg_t*
-new_element2(int syscall, intptr_t value, intptr_t value2)
+new_element2(int syscall, char *value, char *value2)
{
smp_param_t *param = NULL;
@@ -1142,9 +1144,9 @@ new_element2(int syscall, intptr_t value, intptr_t value2)
}
static sandbox_cfg_t*
-new_element(int syscall, intptr_t value)
+new_element(int syscall, char *value)
{
- return new_element2(syscall, value, 0);
+ return new_element2(syscall, value, NULL);
}
#ifdef __NR_stat64
@@ -1158,7 +1160,7 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_stat, (intptr_t)(void*) file);
+ elem = new_element(SCMP_stat, file);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1171,33 +1173,11 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
}
int
-sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
- rc = sandbox_cfg_allow_stat_filename(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_stat_filename_array fail");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- return 0;
-}
-
-int
sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_SYS(open), (intptr_t)(void *) file);
+ elem = new_element(SCMP_SYS(open), file);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1214,9 +1194,7 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element2(SCMP_SYS(rename),
- (intptr_t)(void *) file1,
- (intptr_t)(void *) file2);
+ elem = new_element2(SCMP_SYS(rename), file1, file2);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
@@ -1230,33 +1208,11 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
}
int
-sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
- rc = sandbox_cfg_allow_open_filename(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_open_filename_array fail");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- return 0;
-}
-
-int
sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_SYS(openat), (intptr_t)(void *) file);
+ elem = new_element(SCMP_SYS(openat), file);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1268,35 +1224,13 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
return 0;
}
-int
-sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
- rc = sandbox_cfg_allow_openat_filename(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_openat_filename_array fail");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- return 0;
-}
-
#if 0
int
sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
{
sandbox_cfg_t *elem = NULL;
- elem = new_element(SCMP_SYS(execve), (intptr_t)(void *) com);
+ elem = new_element(SCMP_SYS(execve), com);
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
@@ -1308,28 +1242,6 @@ sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
return 0;
}
-int
-sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...)
-{
- int rc = 0;
- char *fn = NULL;
-
- va_list ap;
- va_start(ap, cfg);
-
- while ((fn = va_arg(ap, char*)) != NULL) {
-
- rc = sandbox_cfg_allow_execve(cfg, fn);
- if (rc) {
- log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_execve_array failed");
- goto end;
- }
- }
-
- end:
- va_end(ap);
- return 0;
-}
#endif
/** Cache entry for getaddrinfo results; used when sandboxing is implemented
@@ -1380,10 +1292,10 @@ static HT_HEAD(getaddrinfo_cache, cached_getaddrinfo_item_t)
HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
cached_getaddrinfo_item_hash,
cached_getaddrinfo_items_eq);
-HT_GENERATE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
- cached_getaddrinfo_item_hash,
- cached_getaddrinfo_items_eq,
- 0.6, tor_malloc_, tor_realloc_, tor_free_);
+HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
+ cached_getaddrinfo_item_hash,
+ cached_getaddrinfo_items_eq,
+ 0.6, tor_reallocarray_, tor_free_)
/** If true, don't try to cache getaddrinfo results. */
static int sandbox_getaddrinfo_cache_disabled = 0;
@@ -1788,26 +1700,12 @@ sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file)
}
int
-sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
-
-int
sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file)
{
(void)cfg; (void)file;
return 0;
}
-int
-sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
-
#if 0
int
sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
@@ -1815,13 +1713,6 @@ sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com)
(void)cfg; (void)com;
return 0;
}
-
-int
-sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
#endif
int
@@ -1832,13 +1723,6 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file)
}
int
-sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...)
-{
- (void)cfg;
- return 0;
-}
-
-int
sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2)
{
(void)cfg; (void)file1; (void)file2;
diff --git a/src/common/sandbox.h b/src/common/sandbox.h
index 35d87772fd..ddb2be5695 100644
--- a/src/common/sandbox.h
+++ b/src/common/sandbox.h
@@ -66,9 +66,9 @@ typedef struct smp_param {
int syscall;
/** parameter value. */
- intptr_t value;
+ char *value;
/** parameter value, second argument. */
- intptr_t value2;
+ char *value2;
/** parameter flag (0 = not protected, 1 = protected). */
int prot;
@@ -149,14 +149,6 @@ int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file);
/**DOCDOC*/
int sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2);
-/** Function used to add a series of open allowed filenames to a supplied
- * configuration.
- * @param cfg sandbox configuration.
- * @param ... a list of stealable pointers to permitted files. The last
- * one must be NULL.
-*/
-int sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...);
-
/**
* Function used to add a openat allowed filename to a supplied configuration.
* The (char*) specifies the path to the allowed file; we steal the pointer to
@@ -164,28 +156,12 @@ int sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...);
*/
int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file);
-/** Function used to add a series of openat allowed filenames to a supplied
- * configuration.
- * @param cfg sandbox configuration.
- * @param ... a list of stealable pointers to permitted files. The last
- * one must be NULL.
- */
-int sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...);
-
#if 0
/**
* Function used to add a execve allowed filename to a supplied configuration.
* The (char*) specifies the path to the allowed file; that pointer is stolen.
*/
int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com);
-
-/** Function used to add a series of execve allowed filenames to a supplied
- * configuration.
- * @param cfg sandbox configuration.
- * @param ... an array of stealable pointers to permitted files. The last
- * one must be NULL.
- */
-int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...);
#endif
/**
@@ -194,14 +170,6 @@ int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...);
*/
int sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file);
-/** Function used to add a series of stat64 allowed filenames to a supplied
- * configuration.
- * @param cfg sandbox configuration.
- * @param ... an array of stealable pointers to permitted files. The last
- * one must be NULL.
- */
-int sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...);
-
/** Function used to initialise a sandbox configuration.*/
int sandbox_init(sandbox_cfg_t* cfg);
diff --git a/src/common/torgzip.c b/src/common/torgzip.c
index 15451ee30d..b4688bf9d8 100644
--- a/src/common/torgzip.c
+++ b/src/common/torgzip.c
@@ -46,6 +46,12 @@
#include <zlib.h>
+static size_t tor_zlib_state_size_precalc(int inflate,
+ int windowbits, int memlevel);
+
+/** Total number of bytes allocated for zlib state */
+static size_t total_zlib_allocation = 0;
+
/** Set to 1 if zlib is a version that supports gzip; set to 0 if it doesn't;
* set to -1 if we haven't checked yet. */
static int gzip_is_supported = -1;
@@ -411,6 +417,9 @@ struct tor_zlib_state_t {
size_t input_so_far;
/** Number of bytes written so far. Used to detect zlib bombs. */
size_t output_so_far;
+
+ /** Approximate number of bytes allocated for this object. */
+ size_t allocation;
};
/** Construct and return a tor_zlib_state_t object using <b>method</b>. If
@@ -420,6 +429,7 @@ tor_zlib_state_t *
tor_zlib_new(int compress, compress_method_t method)
{
tor_zlib_state_t *out;
+ int bits;
if (method == GZIP_METHOD && !is_gzip_supported()) {
/* Old zlib version don't support gzip in inflateInit2 */
@@ -432,14 +442,19 @@ tor_zlib_new(int compress, compress_method_t method)
out->stream.zfree = Z_NULL;
out->stream.opaque = NULL;
out->compress = compress;
+ bits = method_bits(method);
if (compress) {
if (deflateInit2(&out->stream, Z_BEST_COMPRESSION, Z_DEFLATED,
- method_bits(method), 8, Z_DEFAULT_STRATEGY) != Z_OK)
+ bits, 8, Z_DEFAULT_STRATEGY) != Z_OK)
goto err;
} else {
- if (inflateInit2(&out->stream, method_bits(method)) != Z_OK)
+ if (inflateInit2(&out->stream, bits) != Z_OK)
goto err;
}
+ out->allocation = tor_zlib_state_size_precalc(!compress, bits, 8);
+
+ total_zlib_allocation += out->allocation;
+
return out;
err:
@@ -472,7 +487,7 @@ tor_zlib_process(tor_zlib_state_t *state,
state->stream.avail_out = (unsigned int)*out_len;
if (state->compress) {
- err = deflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH);
+ err = deflate(&state->stream, finish ? Z_FINISH : Z_NO_FLUSH);
} else {
err = inflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH);
}
@@ -517,6 +532,8 @@ tor_zlib_free(tor_zlib_state_t *state)
if (!state)
return;
+ total_zlib_allocation -= state->allocation;
+
if (state->compress)
deflateEnd(&state->stream);
else
@@ -525,3 +542,48 @@ tor_zlib_free(tor_zlib_state_t *state)
tor_free(state);
}
+/** Return an approximate number of bytes used in RAM to hold a state with
+ * window bits <b>windowBits</b> and compression level 'memlevel' */
+static size_t
+tor_zlib_state_size_precalc(int inflate, int windowbits, int memlevel)
+{
+ windowbits &= 15;
+
+#define A_FEW_KILOBYTES 2048
+
+ if (inflate) {
+ /* From zconf.h:
+
+ "The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects."
+ */
+ return sizeof(tor_zlib_state_t) + sizeof(struct z_stream_s) +
+ (1 << 15) + A_FEW_KILOBYTES;
+ } else {
+ /* Also from zconf.h:
+
+ "The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ ... plus a few kilobytes for small objects."
+ */
+ return sizeof(tor_zlib_state_t) + sizeof(struct z_stream_s) +
+ (1 << (windowbits + 2)) + (1 << (memlevel + 9)) + A_FEW_KILOBYTES;
+ }
+#undef A_FEW_KILOBYTES
+}
+
+/** Return the approximate number of bytes allocated for <b>state</b>. */
+size_t
+tor_zlib_state_size(const tor_zlib_state_t *state)
+{
+ return state->allocation;
+}
+
+/** Return the approximate number of bytes allocated for all zlib states. */
+size_t
+tor_zlib_get_total_allocation(void)
+{
+ return total_zlib_allocation;
+}
+
diff --git a/src/common/torgzip.h b/src/common/torgzip.h
index 5db03fe6e0..d407bf48c6 100644
--- a/src/common/torgzip.h
+++ b/src/common/torgzip.h
@@ -55,5 +55,8 @@ tor_zlib_output_t tor_zlib_process(tor_zlib_state_t *state,
int finish);
void tor_zlib_free(tor_zlib_state_t *state);
+size_t tor_zlib_state_size(const tor_zlib_state_t *state);
+size_t tor_zlib_get_total_allocation(void);
+
#endif
diff --git a/src/common/torint.h b/src/common/torint.h
index a993d7649a..b46f306668 100644
--- a/src/common/torint.h
+++ b/src/common/torint.h
@@ -332,30 +332,30 @@ typedef uint32_t uintptr_t;
#endif /* time_t_is_signed */
#endif /* ifndef(TIME_MAX) */
-#ifndef SIZE_T_MAX
+#ifndef SIZE_MAX
#if (SIZEOF_SIZE_T == 4)
-#define SIZE_T_MAX UINT32_MAX
+#define SIZE_MAX UINT32_MAX
#elif (SIZEOF_SIZE_T == 8)
-#define SIZE_T_MAX UINT64_MAX
+#define SIZE_MAX UINT64_MAX
#else
-#error "Can't define SIZE_T_MAX"
+#error "Can't define SIZE_MAX"
#endif
#endif
-#ifndef SSIZE_T_MAX
+#ifndef SSIZE_MAX
#if (SIZEOF_SIZE_T == 4)
-#define SSIZE_T_MAX INT32_MAX
+#define SSIZE_MAX INT32_MAX
#elif (SIZEOF_SIZE_T == 8)
-#define SSIZE_T_MAX INT64_MAX
+#define SSIZE_MAX INT64_MAX
#else
-#error "Can't define SSIZE_T_MAX"
+#error "Can't define SSIZE_MAX"
#endif
#endif
/** Any ssize_t larger than this amount is likely to be an underflow. */
-#define SSIZE_T_CEILING ((ssize_t)(SSIZE_T_MAX-16))
+#define SSIZE_T_CEILING ((ssize_t)(SSIZE_MAX-16))
/** Any size_t larger than this amount is likely to be an underflow. */
-#define SIZE_T_CEILING ((size_t)(SSIZE_T_MAX-16))
+#define SIZE_T_CEILING ((size_t)(SSIZE_MAX-16))
#endif /* __TORINT_H */
diff --git a/src/common/torlog.h b/src/common/torlog.h
index 34f70f3c00..34e39b4b94 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -130,7 +130,8 @@ void set_log_severity_config(int minSeverity, int maxSeverity,
log_severity_list_t *severity_out);
void add_stream_log(const log_severity_list_t *severity, const char *name,
int fd);
-int add_file_log(const log_severity_list_t *severity, const char *filename);
+int add_file_log(const log_severity_list_t *severity, const char *filename,
+ const int truncate);
#ifdef HAVE_SYSLOG_H
int add_syslog_log(const log_severity_list_t *severity);
#endif
@@ -148,6 +149,7 @@ void change_callback_log_severity(int loglevelMin, int loglevelMax,
void flush_pending_log_callbacks(void);
void log_set_application_name(const char *name);
void set_log_time_granularity(int granularity_msec);
+void truncate_logs(void);
void tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
CHECK_PRINTF(3,4);
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 4fd9bba380..eda10bbe2e 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -16,10 +16,6 @@
#include "orconfig.h"
-#if defined (WINCE)
-#include <WinSock2.h>
-#endif
-
#include <assert.h>
#ifdef _WIN32 /*wrkard for dtls1.h >= 0.9.8m of "#include <winsock.h>"*/
#ifndef _WIN32_WINNT
@@ -786,8 +782,7 @@ static const cipher_info_t CLIENT_CIPHER_INFO_LIST[] = {
};
/** The length of CLIENT_CIPHER_INFO_LIST and CLIENT_CIPHER_DUMMIES. */
-static const int N_CLIENT_CIPHERS =
- sizeof(CLIENT_CIPHER_INFO_LIST)/sizeof(CLIENT_CIPHER_INFO_LIST[0]);
+static const int N_CLIENT_CIPHERS = ARRAY_LENGTH(CLIENT_CIPHER_INFO_LIST);
#endif
#ifndef V2_HANDSHAKE_CLIENT
@@ -2615,16 +2610,20 @@ check_no_tls_errors_(const char *fname, int line)
int
tor_tls_used_v1_handshake(tor_tls_t *tls)
{
+#if defined(V2_HANDSHAKE_SERVER) && defined(V2_HANDSHAKE_CLIENT)
+ return ! tls->wasV2Handshake;
+#else
if (tls->isServer) {
-#ifdef V2_HANDSHAKE_SERVER
+# ifdef V2_HANDSHAKE_SERVER
return ! tls->wasV2Handshake;
-#endif
+# endif
} else {
-#ifdef V2_HANDSHAKE_CLIENT
+# ifdef V2_HANDSHAKE_CLIENT
return ! tls->wasV2Handshake;
-#endif
+# endif
}
return 1;
+#endif
}
/** Return true iff <b>name</b> is a DN of a kind that could only
diff --git a/src/common/util.c b/src/common/util.c
index 2d7893b38a..f4d293c838 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -96,6 +96,10 @@
#include <sys/wait.h>
#endif
+#ifdef __clang_analyzer__
+#undef MALLOC_ZERO_WORKS
+#endif
+
/* =====
* Assertion helper.
* ===== */
@@ -231,6 +235,13 @@ tor_realloc_(void *ptr, size_t size DMALLOC_PARAMS)
tor_assert(size < SIZE_T_CEILING);
+#ifndef MALLOC_ZERO_WORKS
+ /* Some libc mallocs don't work when size==0. Override them. */
+ if (size==0) {
+ size=1;
+ }
+#endif
+
#ifdef USE_DMALLOC
result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0);
#else
@@ -244,6 +255,20 @@ tor_realloc_(void *ptr, size_t size DMALLOC_PARAMS)
return result;
}
+/**
+ * Try to realloc <b>ptr</b> so that it takes up sz1 * sz2 bytes. Check for
+ * overflow. Unlike other allocation functions, return NULL on overflow.
+ */
+void *
+tor_reallocarray_(void *ptr, size_t sz1, size_t sz2 DMALLOC_PARAMS)
+{
+ /* XXXX we can make this return 0, but we would need to check all the
+ * reallocarray users. */
+ tor_assert(sz2 == 0 || sz1 < SIZE_T_CEILING / sz2);
+
+ return tor_realloc(ptr, (sz1 * sz2) DMALLOC_FN_ARGS);
+}
+
/** Return a newly allocated copy of the NUL-terminated string s. On
* error, log and terminate. (Like strdup(s), but never returns
* NULL.)
@@ -1183,9 +1208,14 @@ esc_for_log(const char *s)
}
}
+ tor_assert(len <= SSIZE_MAX);
+
result = outp = tor_malloc(len);
*outp++ = '\"';
for (cp = s; *cp; ++cp) {
+ /* This assertion should always succeed, since we will write at least
+ * one char here, and two chars for closing quote and nul later */
+ tor_assert((outp-result) < (ssize_t)len-2);
switch (*cp) {
case '\\':
case '\"':
@@ -1209,6 +1239,7 @@ esc_for_log(const char *s)
if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) {
*outp++ = *cp;
} else {
+ tor_assert((outp-result) < (ssize_t)len-4);
tor_snprintf(outp, 5, "\\%03o", (int)(uint8_t) *cp);
outp += 4;
}
@@ -1216,6 +1247,7 @@ esc_for_log(const char *s)
}
}
+ tor_assert((outp-result) <= (ssize_t)len-2);
*outp++ = '\"';
*outp++ = 0;
@@ -1754,7 +1786,7 @@ write_all(tor_socket_t fd, const char *buf, size_t count, int isSocket)
{
size_t written = 0;
ssize_t result;
- tor_assert(count < SSIZE_T_MAX);
+ tor_assert(count < SSIZE_MAX);
while (written != count) {
if (isSocket)
@@ -1779,7 +1811,7 @@ read_all(tor_socket_t fd, char *buf, size_t count, int isSocket)
size_t numread = 0;
ssize_t result;
- if (count > SIZE_T_CEILING || count > SSIZE_T_MAX)
+ if (count > SIZE_T_CEILING || count > SSIZE_MAX)
return -1;
while (numread != count) {
@@ -1893,7 +1925,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
}
if (check & CPD_CREATE) {
log_info(LD_GENERAL, "Creating directory %s", dirname);
-#if defined (_WIN32) && !defined (WINCE)
+#if defined (_WIN32)
r = mkdir(dirname);
#else
r = mkdir(dirname, 0700);
@@ -2332,6 +2364,7 @@ read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out)
pos += r;
} while (r > 0 && pos < max_bytes_to_read);
+ tor_assert(pos < string_max);
*sz_out = pos;
string[pos] = '\0';
return string;
@@ -2804,10 +2837,14 @@ scan_unsigned(const char **bufp, unsigned long *out, int width, int base)
while (**bufp && (hex?TOR_ISXDIGIT(**bufp):TOR_ISDIGIT(**bufp))
&& scanned_so_far < width) {
int digit = hex?hex_decode_digit(*(*bufp)++):digit_to_num(*(*bufp)++);
- unsigned long new_result = result * base + digit;
- if (new_result < result)
- return -1; /* over/underflow. */
- result = new_result;
+ // Check for overflow beforehand, without actually causing any overflow
+ // This preserves functionality on compilers that don't wrap overflow
+ // (i.e. that trap or optimise away overflow)
+ // result * base + digit > ULONG_MAX
+ // result * base > ULONG_MAX - digit
+ if (result > (ULONG_MAX - digit)/base)
+ return -1; /* Processing this digit would overflow */
+ result = result * base + digit;
++scanned_so_far;
}
@@ -2842,10 +2879,17 @@ scan_signed(const char **bufp, long *out, int width)
if (scan_unsigned(bufp, &result, width, 10) < 0)
return -1;
- if (neg) {
+ if (neg && result > 0) {
if (result > ((unsigned long)LONG_MAX) + 1)
return -1; /* Underflow */
- *out = -(long)result;
+ // Avoid overflow on the cast to signed long when result is LONG_MIN
+ // by subtracting 1 from the unsigned long positive value,
+ // then, after it has been cast to signed and negated,
+ // subtracting the original 1 (the double-subtraction is intentional).
+ // Otherwise, the cast to signed could cause a temporary long
+ // to equal LONG_MAX + 1, which is undefined.
+ // We avoid underflow on the subtraction by treating -0 as positive.
+ *out = (-(long)(result - 1)) - 1;
} else {
if (result > LONG_MAX)
return -1; /* Overflow */
@@ -3378,8 +3422,8 @@ format_win_cmdline_argument(const char *arg)
smartlist_add(arg_chars, (void*)&backslash);
/* Allocate space for argument, quotes (if needed), and terminator */
- formatted_arg = tor_malloc(sizeof(char) *
- (smartlist_len(arg_chars) + (need_quotes?2:0) + 1));
+ formatted_arg = tor_calloc(sizeof(char),
+ (smartlist_len(arg_chars) + (need_quotes ? 2 : 0) + 1));
/* Add leading quote */
i=0;
@@ -3544,7 +3588,13 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
/* Convert errno to be unsigned for hex conversion */
if (saved_errno < 0) {
- unsigned_errno = (unsigned int) -saved_errno;
+ // Avoid overflow on the cast to unsigned int when result is INT_MIN
+ // by adding 1 to the signed int negative value,
+ // then, after it has been negated and cast to unsigned,
+ // adding the original 1 back (the double-addition is intentional).
+ // Otherwise, the cast to signed could cause a temporary int
+ // to equal INT_MAX + 1, which is undefined.
+ unsigned_errno = ((unsigned int) -(saved_errno + 1)) + 1;
} else {
unsigned_errno = (unsigned int) saved_errno;
}
@@ -4038,8 +4088,11 @@ tor_spawn_background(const char *const filename, const char **argv,
status = process_handle->status = PROCESS_STATUS_RUNNING;
/* Set stdout/stderr pipes to be non-blocking */
- fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK);
- fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK);
+ if (fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK) < 0 ||
+ fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK) < 0) {
+ log_warn(LD_GENERAL, "Failed to set stderror/stdout pipes nonblocking "
+ "in parent process: %s", strerror(errno));
+ }
/* Open the buffered IO streams */
process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r");
process_handle->stderr_handle = fdopen(process_handle->stderr_pipe, "r");
@@ -4373,7 +4426,7 @@ tor_read_all_handle(HANDLE h, char *buf, size_t count,
DWORD byte_count;
BOOL process_exited = FALSE;
- if (count > SIZE_T_CEILING || count > SSIZE_T_MAX)
+ if (count > SIZE_T_CEILING || count > SSIZE_MAX)
return -1;
while (numread != count) {
@@ -4439,7 +4492,7 @@ tor_read_all_handle(FILE *h, char *buf, size_t count,
if (eof)
*eof = 0;
- if (count > SIZE_T_CEILING || count > SSIZE_T_MAX)
+ if (count > SIZE_T_CEILING || count > SSIZE_MAX)
return -1;
while (numread != count) {
@@ -5008,7 +5061,7 @@ tor_check_port_forwarding(const char *filename,
for each smartlist element (one for "-p" and one for the
ports), and one for the final NULL. */
args_n = 1 + 2*smartlist_len(ports_to_forward) + 1;
- argv = tor_malloc_zero(sizeof(char*)*args_n);
+ argv = tor_calloc(sizeof(char *), args_n);
argv[argv_index++] = filename;
SMARTLIST_FOREACH_BEGIN(ports_to_forward, const char *, port) {
diff --git a/src/common/util.h b/src/common/util.h
index 97367a9a7b..61bb05f016 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -79,6 +79,7 @@ void *tor_malloc_(size_t size DMALLOC_PARAMS) ATTR_MALLOC;
void *tor_malloc_zero_(size_t size DMALLOC_PARAMS) ATTR_MALLOC;
void *tor_calloc_(size_t nmemb, size_t size DMALLOC_PARAMS) ATTR_MALLOC;
void *tor_realloc_(void *ptr, size_t size DMALLOC_PARAMS);
+void *tor_reallocarray_(void *ptr, size_t size1, size_t size2 DMALLOC_PARAMS);
char *tor_strdup_(const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1));
char *tor_strndup_(const char *s, size_t n DMALLOC_PARAMS)
ATTR_MALLOC ATTR_NONNULL((1));
@@ -116,6 +117,8 @@ extern int dmalloc_free(const char *file, const int line, void *pnt,
#define tor_malloc_zero(size) tor_malloc_zero_(size DMALLOC_ARGS)
#define tor_calloc(nmemb,size) tor_calloc_(nmemb, size DMALLOC_ARGS)
#define tor_realloc(ptr, size) tor_realloc_(ptr, size DMALLOC_ARGS)
+#define tor_reallocarray(ptr, sz1, sz2) \
+ tor_reallocarray_((ptr), (sz1), (sz2) DMALLOC_ARGS)
#define tor_strdup(s) tor_strdup_(s DMALLOC_ARGS)
#define tor_strndup(s, n) tor_strndup_(s, n DMALLOC_ARGS)
#define tor_memdup(s, n) tor_memdup_(s, n DMALLOC_ARGS)
diff --git a/src/common/util_process.c b/src/common/util_process.c
index d6ef590162..a6a2a9dcd9 100644
--- a/src/common/util_process.c
+++ b/src/common/util_process.c
@@ -62,8 +62,8 @@ static HT_HEAD(process_map, waitpid_callback_t) process_map = HT_INITIALIZER();
HT_PROTOTYPE(process_map, waitpid_callback_t, node, process_map_entry_hash_,
process_map_entries_eq_);
-HT_GENERATE(process_map, waitpid_callback_t, node, process_map_entry_hash_,
- process_map_entries_eq_, 0.6, malloc, realloc, free);
+HT_GENERATE2(process_map, waitpid_callback_t, node, process_map_entry_hash_,
+ process_map_entries_eq_, 0.6, tor_reallocarray_, tor_free_);
/**
* Begin monitoring the child pid <b>pid</b> to see if we get a SIGCHLD for
diff --git a/src/config/include.am b/src/config/include.am
index 35961b829a..c283628513 100644
--- a/src/config/include.am
+++ b/src/config/include.am
@@ -2,7 +2,7 @@ confdir = $(sysconfdir)/tor
tordatadir = $(datadir)/tor
-EXTRA_DIST+= src/config/geoip src/config/geoip6
+EXTRA_DIST+= src/config/geoip src/config/geoip6 src/config/torrc.minimal.in
# fallback-consensus
conf_DATA = src/config/torrc.sample
diff --git a/src/config/torrc.minimal.in b/src/config/torrc.minimal.in
new file mode 100644
index 0000000000..d842fbcaf5
--- /dev/null
+++ b/src/config/torrc.minimal.in
@@ -0,0 +1,192 @@
+## Configuration file for a typical Tor user
+## Last updated 9 October 2013 for Tor 0.2.5.2-alpha.
+## (may or may not work for much older or much newer versions of Tor.)
+##
+## Lines that begin with "## " try to explain what's going on. Lines
+## that begin with just "#" are disabled commands: you can enable them
+## by removing the "#" symbol.
+##
+## See 'man tor', or https://www.torproject.org/docs/tor-manual.html,
+## for more options you can use in this file.
+##
+## Tor will look for this file in various places based on your platform:
+## https://www.torproject.org/docs/faq#torrc
+
+## Tor opens a socks proxy on port 9050 by default -- even if you don't
+## configure one below. Set "SocksPort 0" if you plan to run Tor only
+## as a relay, and not make any local application connections yourself.
+#SocksPort 9050 # Default: Bind to localhost:9050 for local connections.
+#SocksPort 192.168.0.1:9100 # Bind to this address:port too.
+
+## Entry policies to allow/deny SOCKS requests based on IP address.
+## First entry that matches wins. If no SocksPolicy is set, we accept
+## all (and only) requests that reach a SocksPort. Untrusted users who
+## can access your SocksPort may be able to learn about the connections
+## you make.
+#SocksPolicy accept 192.168.0.0/16
+#SocksPolicy reject *
+
+## Logs go to stdout at level "notice" unless redirected by something
+## else, like one of the below lines. You can have as many Log lines as
+## you want.
+##
+## We advise using "notice" in most cases, since anything more verbose
+## may provide sensitive information to an attacker who obtains the logs.
+##
+## Send all messages of level 'notice' or higher to @LOCALSTATEDIR@/log/tor/notices.log
+#Log notice file @LOCALSTATEDIR@/log/tor/notices.log
+## Send every possible message to @LOCALSTATEDIR@/log/tor/debug.log
+#Log debug file @LOCALSTATEDIR@/log/tor/debug.log
+## Use the system log instead of Tor's logfiles
+#Log notice syslog
+## To send all messages to stderr:
+#Log debug stderr
+
+## Uncomment this to start the process in the background... or use
+## --runasdaemon 1 on the command line. This is ignored on Windows;
+## see the FAQ entry if you want Tor to run as an NT service.
+#RunAsDaemon 1
+
+## The directory for keeping all the keys/etc. By default, we store
+## things in $HOME/.tor on Unix, and in Application Data\tor on Windows.
+#DataDirectory @LOCALSTATEDIR@/lib/tor
+
+## The port on which Tor will listen for local connections from Tor
+## controller applications, as documented in control-spec.txt.
+#ControlPort 9051
+## If you enable the controlport, be sure to enable one of these
+## authentication methods, to prevent attackers from accessing it.
+#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
+#CookieAuthentication 1
+
+############### This section is just for location-hidden services ###
+
+## Once you have configured a hidden service, you can look at the
+## contents of the file ".../hidden_service/hostname" for the address
+## to tell people.
+##
+## HiddenServicePort x y:z says to redirect requests on port x to the
+## address y:z.
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+#HiddenServicePort 22 127.0.0.1:22
+
+################ This section is just for relays #####################
+#
+## See https://www.torproject.org/docs/tor-doc-relay for details.
+
+## Required: what port to advertise for incoming Tor connections.
+#ORPort 9001
+## If you want to listen on a port other than the one advertised in
+## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as
+## follows. You'll need to do ipchains or other port forwarding
+## yourself to make this work.
+#ORPort 443 NoListen
+#ORPort 127.0.0.1:9090 NoAdvertise
+
+## The IP address or full DNS name for incoming connections to your
+## relay. Leave commented out and Tor will guess.
+#Address noname.example.com
+
+## If you have multiple network interfaces, you can specify one for
+## outgoing traffic to use.
+# OutboundBindAddress 10.0.0.5
+
+## A handle for your relay, so people don't have to refer to it by key.
+#Nickname ididnteditheconfig
+
+## Define these to limit how much relayed traffic you will allow. Your
+## own traffic is still unthrottled. Note that RelayBandwidthRate must
+## be at least 20 KB.
+## Note that units for these config options are bytes per second, not bits
+## per second, and that prefixes are binary prefixes, i.e. 2^10, 2^20, etc.
+#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps)
+#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)
+
+## Use these to restrict the maximum traffic per day, week, or month.
+## Note that this threshold applies separately to sent and received bytes,
+## not to their sum: setting "4 GB" may allow up to 8 GB total before
+## hibernating.
+##
+## Set a maximum of 4 gigabytes each way per period.
+#AccountingMax 4 GB
+## Each period starts daily at midnight (AccountingMax is per day)
+#AccountingStart day 00:00
+## Each period starts on the 3rd of the month at 15:00 (AccountingMax
+## is per month)
+#AccountingStart month 3 15:00
+
+## Administrative contact information for this relay or bridge. This line
+## can be used to contact you if your relay or bridge is misconfigured or
+## something else goes wrong. Note that we archive and publish all
+## descriptors containing these lines and that Google indexes them, so
+## spammers might also collect them. You may want to obscure the fact that
+## it's an email address and/or generate a new address for this purpose.
+#ContactInfo Random Person <nobody AT example dot com>
+## You might also include your PGP or GPG fingerprint if you have one:
+#ContactInfo 0xFFFFFFFF Random Person <nobody AT example dot com>
+
+## Uncomment this to mirror directory information for others. Please do
+## if you have enough bandwidth.
+#DirPort 9030 # what port to advertise for directory connections
+## If you want to listen on a port other than the one advertised in
+## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as
+## follows. below too. You'll need to do ipchains or other port
+## forwarding yourself to make this work.
+#DirPort 80 NoListen
+#DirPort 127.0.0.1:9091 NoAdvertise
+## Uncomment to return an arbitrary blob of html on your DirPort. Now you
+## can explain what Tor is if anybody wonders why your IP address is
+## contacting them. See contrib/tor-exit-notice.html in Tor's source
+## distribution for a sample.
+#DirPortFrontPage @CONFDIR@/tor-exit-notice.html
+
+## Uncomment this if you run more than one Tor relay, and add the identity
+## key fingerprint of each Tor relay you control, even if they're on
+## different networks. You declare it here so Tor clients can avoid
+## using more than one of your relays in a single circuit. See
+## https://www.torproject.org/docs/faq#MultipleRelays
+## However, you should never include a bridge's fingerprint here, as it would
+## break its concealability and potentionally reveal its IP/TCP address.
+#MyFamily $keyid,$keyid,...
+
+## A comma-separated list of exit policies. They're considered first
+## to last, and the first match wins. If you want to _replace_
+## the default exit policy, end this with either a reject *:* or an
+## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
+## default exit policy. Leave commented to just use the default, which is
+## described in the man page or at
+## https://www.torproject.org/documentation.html
+##
+## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
+## for issues you might encounter if you use the default exit policy.
+##
+## If certain IPs and ports are blocked externally, e.g. by your firewall,
+## you should update your exit policy to reflect this -- otherwise Tor
+## users will be told that those destinations are down.
+##
+## For security, by default Tor rejects connections to private (local)
+## networks, including to your public IP address. See the man page entry
+## for ExitPolicyRejectPrivate if you want to allow "exit enclaving".
+##
+#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
+#ExitPolicy accept *:119 # accept nntp as well as default exit policy
+#ExitPolicy reject *:* # no exits allowed
+
+## Bridge relays (or "bridges") are Tor relays that aren't listed in the
+## main directory. Since there is no complete public list of them, even an
+## ISP that filters connections to all the known Tor relays probably
+## won't be able to block all the bridges. Also, websites won't treat you
+## differently because they won't know you're running Tor. If you can
+## be a real relay, please do; but if not, be a bridge!
+#BridgeRelay 1
+## By default, Tor will advertise your bridge to users through various
+## mechanisms like https://bridges.torproject.org/. If you want to run
+## a private bridge, for example because you'll give out your bridge
+## address manually to your friends, uncomment this line:
+#PublishServerDescriptor 0
+
diff --git a/src/config/torrc.minimal.in-staging b/src/config/torrc.minimal.in-staging
new file mode 100644
index 0000000000..bde800fd23
--- /dev/null
+++ b/src/config/torrc.minimal.in-staging
@@ -0,0 +1,193 @@
+## Configuration file for a typical Tor user
+## Last updated 2 September 2014 for Tor 0.2.6.1-alpha.
+## (may or may not work for much older or much newer versions of Tor.)
+##
+## Lines that begin with "## " try to explain what's going on. Lines
+## that begin with just "#" are disabled commands: you can enable them
+## by removing the "#" symbol.
+##
+## See 'man tor', or https://www.torproject.org/docs/tor-manual.html,
+## for more options you can use in this file.
+##
+## Tor will look for this file in various places based on your platform:
+## https://www.torproject.org/docs/faq#torrc
+
+## Tor opens a socks proxy on port 9050 by default -- even if you don't
+## configure one below. Set "SocksPort 0" if you plan to run Tor only
+## as a relay, and not make any local application connections yourself.
+#SocksPort 9050 # Default: Bind to localhost:9050 for local connections.
+#SocksPort 192.168.0.1:9100 # Bind to this address:port too.
+
+## Entry policies to allow/deny SOCKS requests based on IP address.
+## First entry that matches wins. If no SocksPolicy is set, we accept
+## all (and only) requests that reach a SocksPort. Untrusted users who
+## can access your SocksPort may be able to learn about the connections
+## you make.
+#SocksPolicy accept 192.168.0.0/16
+#SocksPolicy reject *
+
+## Logs go to stdout at level "notice" unless redirected by something
+## else, like one of the below lines. You can have as many Log lines as
+## you want.
+##
+## We advise using "notice" in most cases, since anything more verbose
+## may provide sensitive information to an attacker who obtains the logs.
+##
+## Send all messages of level 'notice' or higher to @LOCALSTATEDIR@/log/tor/notices.log
+#Log notice file @LOCALSTATEDIR@/log/tor/notices.log
+## Send every possible message to @LOCALSTATEDIR@/log/tor/debug.log
+#Log debug file @LOCALSTATEDIR@/log/tor/debug.log
+## Use the system log instead of Tor's logfiles
+#Log notice syslog
+## To send all messages to stderr:
+#Log debug stderr
+
+## Uncomment this to start the process in the background... or use
+## --runasdaemon 1 on the command line. This is ignored on Windows;
+## see the FAQ entry if you want Tor to run as an NT service.
+#RunAsDaemon 1
+
+## The directory for keeping all the keys/etc. By default, we store
+## things in $HOME/.tor on Unix, and in Application Data\tor on Windows.
+#DataDirectory @LOCALSTATEDIR@/lib/tor
+
+## The port on which Tor will listen for local connections from Tor
+## controller applications, as documented in control-spec.txt.
+#ControlPort 9051
+## If you enable the controlport, be sure to enable one of these
+## authentication methods, to prevent attackers from accessing it.
+#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
+#CookieAuthentication 1
+
+############### This section is just for location-hidden services ###
+
+## Once you have configured a hidden service, you can look at the
+## contents of the file ".../hidden_service/hostname" for the address
+## to tell people.
+##
+## HiddenServicePort x y:z says to redirect requests on port x to the
+## address y:z.
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+
+#HiddenServiceDir @LOCALSTATEDIR@/lib/tor/other_hidden_service/
+#HiddenServicePort 80 127.0.0.1:80
+#HiddenServicePort 22 127.0.0.1:22
+
+################ This section is just for relays #####################
+#
+## See https://www.torproject.org/docs/tor-doc-relay for details.
+
+## Required: what port to advertise for incoming Tor connections.
+#ORPort 9001
+## If you want to listen on a port other than the one advertised in
+## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as
+## follows. You'll need to do ipchains or other port forwarding
+## yourself to make this work.
+#ORPort 443 NoListen
+#ORPort 127.0.0.1:9090 NoAdvertise
+
+## The IP address or full DNS name for incoming connections to your
+## relay. Leave commented out and Tor will guess.
+#Address noname.example.com
+
+## If you have multiple network interfaces, you can specify one for
+## outgoing traffic to use.
+# OutboundBindAddress 10.0.0.5
+
+## A handle for your relay, so people don't have to refer to it by key.
+#Nickname ididnteditheconfig
+
+## Define these to limit how much relayed traffic you will allow. Your
+## own traffic is still unthrottled. Note that RelayBandwidthRate must
+## be at least 20 kilobytes per second.
+## Note that units for these config options are bytes (per second), not
+## bits (per second), and that prefixes are binary prefixes, i.e. 2^10,
+## 2^20, etc.
+#RelayBandwidthRate 100 KBytes # Throttle traffic to 100KB/s (800Kbps)
+#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB (1600Kb)
+
+## Use these to restrict the maximum traffic per day, week, or month.
+## Note that this threshold applies separately to sent and received bytes,
+## not to their sum: setting "4 GB" may allow up to 8 GB total before
+## hibernating.
+##
+## Set a maximum of 4 gigabytes each way per period.
+#AccountingMax 4 GBytes
+## Each period starts daily at midnight (AccountingMax is per day)
+#AccountingStart day 00:00
+## Each period starts on the 3rd of the month at 15:00 (AccountingMax
+## is per month)
+#AccountingStart month 3 15:00
+
+## Administrative contact information for this relay or bridge. This line
+## can be used to contact you if your relay or bridge is misconfigured or
+## something else goes wrong. Note that we archive and publish all
+## descriptors containing these lines and that Google indexes them, so
+## spammers might also collect them. You may want to obscure the fact that
+## it's an email address and/or generate a new address for this purpose.
+#ContactInfo Random Person <nobody AT example dot com>
+## You might also include your PGP or GPG fingerprint if you have one:
+#ContactInfo 0xFFFFFFFF Random Person <nobody AT example dot com>
+
+## Uncomment this to mirror directory information for others. Please do
+## if you have enough bandwidth.
+#DirPort 9030 # what port to advertise for directory connections
+## If you want to listen on a port other than the one advertised in
+## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as
+## follows. below too. You'll need to do ipchains or other port
+## forwarding yourself to make this work.
+#DirPort 80 NoListen
+#DirPort 127.0.0.1:9091 NoAdvertise
+## Uncomment to return an arbitrary blob of html on your DirPort. Now you
+## can explain what Tor is if anybody wonders why your IP address is
+## contacting them. See contrib/tor-exit-notice.html in Tor's source
+## distribution for a sample.
+#DirPortFrontPage @CONFDIR@/tor-exit-notice.html
+
+## Uncomment this if you run more than one Tor relay, and add the identity
+## key fingerprint of each Tor relay you control, even if they're on
+## different networks. You declare it here so Tor clients can avoid
+## using more than one of your relays in a single circuit. See
+## https://www.torproject.org/docs/faq#MultipleRelays
+## However, you should never include a bridge's fingerprint here, as it would
+## break its concealability and potentially reveal its IP/TCP address.
+#MyFamily $keyid,$keyid,...
+
+## A comma-separated list of exit policies. They're considered first
+## to last, and the first match wins. If you want to _replace_
+## the default exit policy, end this with either a reject *:* or an
+## accept *:*. Otherwise, you're _augmenting_ (prepending to) the
+## default exit policy. Leave commented to just use the default, which is
+## described in the man page or at
+## https://www.torproject.org/documentation.html
+##
+## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
+## for issues you might encounter if you use the default exit policy.
+##
+## If certain IPs and ports are blocked externally, e.g. by your firewall,
+## you should update your exit policy to reflect this -- otherwise Tor
+## users will be told that those destinations are down.
+##
+## For security, by default Tor rejects connections to private (local)
+## networks, including to your public IP address. See the man page entry
+## for ExitPolicyRejectPrivate if you want to allow "exit enclaving".
+##
+#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
+#ExitPolicy accept *:119 # accept nntp as well as default exit policy
+#ExitPolicy reject *:* # no exits allowed
+
+## Bridge relays (or "bridges") are Tor relays that aren't listed in the
+## main directory. Since there is no complete public list of them, even an
+## ISP that filters connections to all the known Tor relays probably
+## won't be able to block all the bridges. Also, websites won't treat you
+## differently because they won't know you're running Tor. If you can
+## be a real relay, please do; but if not, be a bridge!
+#BridgeRelay 1
+## By default, Tor will advertise your bridge to users through various
+## mechanisms like https://bridges.torproject.org/. If you want to run
+## a private bridge, for example because you'll give out your bridge
+## address manually to your friends, uncomment this line:
+#PublishServerDescriptor 0
+
diff --git a/src/config/torrc.sample.in b/src/config/torrc.sample.in
index d842fbcaf5..bde800fd23 100644
--- a/src/config/torrc.sample.in
+++ b/src/config/torrc.sample.in
@@ -1,5 +1,5 @@
## Configuration file for a typical Tor user
-## Last updated 9 October 2013 for Tor 0.2.5.2-alpha.
+## Last updated 2 September 2014 for Tor 0.2.6.1-alpha.
## (may or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
@@ -101,11 +101,12 @@
## Define these to limit how much relayed traffic you will allow. Your
## own traffic is still unthrottled. Note that RelayBandwidthRate must
-## be at least 20 KB.
-## Note that units for these config options are bytes per second, not bits
-## per second, and that prefixes are binary prefixes, i.e. 2^10, 2^20, etc.
-#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps)
-#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)
+## be at least 20 kilobytes per second.
+## Note that units for these config options are bytes (per second), not
+## bits (per second), and that prefixes are binary prefixes, i.e. 2^10,
+## 2^20, etc.
+#RelayBandwidthRate 100 KBytes # Throttle traffic to 100KB/s (800Kbps)
+#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB (1600Kb)
## Use these to restrict the maximum traffic per day, week, or month.
## Note that this threshold applies separately to sent and received bytes,
@@ -113,7 +114,7 @@
## hibernating.
##
## Set a maximum of 4 gigabytes each way per period.
-#AccountingMax 4 GB
+#AccountingMax 4 GBytes
## Each period starts daily at midnight (AccountingMax is per day)
#AccountingStart day 00:00
## Each period starts on the 3rd of the month at 15:00 (AccountingMax
@@ -151,7 +152,7 @@
## using more than one of your relays in a single circuit. See
## https://www.torproject.org/docs/faq#MultipleRelays
## However, you should never include a bridge's fingerprint here, as it would
-## break its concealability and potentionally reveal its IP/TCP address.
+## break its concealability and potentially reveal its IP/TCP address.
#MyFamily $keyid,$keyid,...
## A comma-separated list of exit policies. They're considered first
diff --git a/src/ext/OpenBSD_malloc_Linux.c b/src/ext/OpenBSD_malloc_Linux.c
index da82729811..855c912310 100644
--- a/src/ext/OpenBSD_malloc_Linux.c
+++ b/src/ext/OpenBSD_malloc_Linux.c
@@ -58,7 +58,7 @@
#include <limits.h>
#include <errno.h>
#include <err.h>
-/* For SIZE_T_MAX */
+/* For SIZE_MAX */
#include "torint.h"
//#include "thread_private.h"
@@ -1961,16 +1961,6 @@ realloc(void *ptr, size_t size)
return (r);
}
-#ifndef SIZE_MAX
-//#if defined(__i386__)||defined(__arm__)||defined(__powerpc__)
-//#define SIZE_MAX 0xffffffff
-//#endif
-//#if defined(__x86_64__)
-//#define SIZE_MAX 0xffffffffffffffff
-//#endif
-#define SIZE_MAX SIZE_T_MAX
-#endif
-
void *
calloc(size_t num, size_t size)
{
diff --git a/src/ext/README b/src/ext/README
index 5d5a6e1518..616716e099 100644
--- a/src/ext/README
+++ b/src/ext/README
@@ -49,3 +49,15 @@ siphash.h
Marek Majkowski's implementation of siphash 2-4, a secure keyed
hash algorithm to avoid collision-based DoS attacks against hash
tables.
+
+trunnel/*.[ch]
+
+ Headers and runtime code for Trunnel, a system for generating
+ code to encode and decode binary formats.
+
+ed25519/ref10/*
+
+ Daniel Bernsten's portable ref10 implementation of ed25519.
+ Public domain.
+
+
diff --git a/src/ext/ed25519/ref10/Makefile b/src/ext/ed25519/ref10/Makefile
new file mode 100644
index 0000000000..9b0ba7ad45
--- /dev/null
+++ b/src/ext/ed25519/ref10/Makefile
@@ -0,0 +1,41 @@
+all: d.h d2.h sqrtm1.h base.h base2.h \
+ge_add.h ge_sub.h \
+ge_madd.h ge_msub.h \
+ge_p2_dbl.h \
+pow225521.h pow22523.h
+
+d.h: d.py
+ python d.py > d.h
+
+d2.h: d2.py
+ python d2.py > d2.h
+
+sqrtm1.h: sqrtm1.py
+ python sqrtm1.py > sqrtm1.h
+
+base.h: base.py
+ python base.py > base.h
+
+base2.h: base2.py
+ python base2.py > base2.h
+
+ge_add.h: ge_add.q q2h.sh
+ ./q2h.sh < ge_add.q > ge_add.h
+
+ge_sub.h: ge_sub.q q2h.sh
+ ./q2h.sh < ge_sub.q > ge_sub.h
+
+ge_madd.h: ge_madd.q q2h.sh
+ ./q2h.sh < ge_madd.q > ge_madd.h
+
+ge_msub.h: ge_msub.q q2h.sh
+ ./q2h.sh < ge_msub.q > ge_msub.h
+
+ge_p2_dbl.h: ge_p2_dbl.q q2h.sh
+ ./q2h.sh < ge_p2_dbl.q > ge_p2_dbl.h
+
+pow22523.h: pow22523.q q2h.sh
+ ./q2h.sh < pow22523.q > pow22523.h
+
+pow225521.h: pow225521.q q2h.sh
+ ./q2h.sh < pow225521.q > pow225521.h
diff --git a/src/ext/ed25519/ref10/README.tor b/src/ext/ed25519/ref10/README.tor
new file mode 100644
index 0000000000..38ed97ba05
--- /dev/null
+++ b/src/ext/ed25519/ref10/README.tor
@@ -0,0 +1,23 @@
+
+We've made the following changes to the stock ed25519_ref10 from
+supercop-20140622:
+
+ * We added the necessary glue to provide integers of fixed bit
+ sizes, SHA512, and to compile without warnings everywhere we need
+ to build.
+
+ * Secret keys are stored in expanded format. There are functions
+ to expand them from the 32-byte seed.
+
+ * Signatures are made and processed detached from the messages that
+ they sign. (In other words, we support "make signature" and
+ "check signature", not "create signed message" and "check and
+ unpack signed message".)
+
+ * There's an implementation of 'convert a curve25519 key to an
+ ed25519 key' so we can do cross-certification with curve25519 keys.
+ (keyconv.c)
+
+ * There's an implementation of multiplicative key blinding so we
+ can use it for next-gen hidden srevice descriptors. (blinding.c)
+
diff --git a/src/ext/ed25519/ref10/api.h b/src/ext/ed25519/ref10/api.h
new file mode 100644
index 0000000000..d88dae0c32
--- /dev/null
+++ b/src/ext/ed25519/ref10/api.h
@@ -0,0 +1,4 @@
+#define CRYPTO_SECRETKEYBYTES 64
+#define CRYPTO_PUBLICKEYBYTES 32
+#define CRYPTO_BYTES 64
+#define CRYPTO_DETERMINISTIC 1
diff --git a/src/ext/ed25519/ref10/base.h b/src/ext/ed25519/ref10/base.h
new file mode 100644
index 0000000000..573bd8a05c
--- /dev/null
+++ b/src/ext/ed25519/ref10/base.h
@@ -0,0 +1,1344 @@
+{
+ {
+ { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 },
+ { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 },
+ { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 },
+ },
+ {
+ { -12815894,-12976347,-21581243,11784320,-25355658,-2750717,-11717903,-3814571,-358445,-10211303 },
+ { -21703237,6903825,27185491,6451973,-29577724,-9554005,-15616551,11189268,-26829678,-5319081 },
+ { 26966642,11152617,32442495,15396054,14353839,-12752335,-3128826,-9541118,-15472047,-4166697 },
+ },
+ {
+ { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 },
+ { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 },
+ { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 },
+ },
+ {
+ { -17036878,13921892,10945806,-6033431,27105052,-16084379,-28926210,15006023,3284568,-6276540 },
+ { 23599295,-8306047,-11193664,-7687416,13236774,10506355,7464579,9656445,13059162,10374397 },
+ { 7798556,16710257,3033922,2874086,28997861,2835604,32406664,-3839045,-641708,-101325 },
+ },
+ {
+ { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 },
+ { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 },
+ { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 },
+ },
+ {
+ { -15371964,-12862754,32573250,4720197,-26436522,5875511,-19188627,-15224819,-9818940,-12085777 },
+ { -8549212,109983,15149363,2178705,22900618,4543417,3044240,-15689887,1762328,14866737 },
+ { -18199695,-15951423,-10473290,1707278,-17185920,3916101,-28236412,3959421,27914454,4383652 },
+ },
+ {
+ { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 },
+ { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 },
+ { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 },
+ },
+ {
+ { 14499471,-2729599,-33191113,-4254652,28494862,14271267,30290735,10876454,-33154098,2381726 },
+ { -7195431,-2655363,-14730155,462251,-27724326,3941372,-6236617,3696005,-32300832,15351955 },
+ { 27431194,8222322,16448760,-3907995,-18707002,11938355,-32961401,-2970515,29551813,10109425 },
+ },
+},
+{
+ {
+ { -13657040,-13155431,-31283750,11777098,21447386,6519384,-2378284,-1627556,10092783,-4764171 },
+ { 27939166,14210322,4677035,16277044,-22964462,-12398139,-32508754,12005538,-17810127,12803510 },
+ { 17228999,-15661624,-1233527,300140,-1224870,-11714777,30364213,-9038194,18016357,4397660 },
+ },
+ {
+ { -10958843,-7690207,4776341,-14954238,27850028,-15602212,-26619106,14544525,-17477504,982639 },
+ { 29253598,15796703,-2863982,-9908884,10057023,3163536,7332899,-4120128,-21047696,9934963 },
+ { 5793303,16271923,-24131614,-10116404,29188560,1206517,-14747930,4559895,-30123922,-10897950 },
+ },
+ {
+ { -27643952,-11493006,16282657,-11036493,28414021,-15012264,24191034,4541697,-13338309,5500568 },
+ { 12650548,-1497113,9052871,11355358,-17680037,-8400164,-17430592,12264343,10874051,13524335 },
+ { 25556948,-3045990,714651,2510400,23394682,-10415330,33119038,5080568,-22528059,5376628 },
+ },
+ {
+ { -26088264,-4011052,-17013699,-3537628,-6726793,1920897,-22321305,-9447443,4535768,1569007 },
+ { -2255422,14606630,-21692440,-8039818,28430649,8775819,-30494562,3044290,31848280,12543772 },
+ { -22028579,2943893,-31857513,6777306,13784462,-4292203,-27377195,-2062731,7718482,14474653 },
+ },
+ {
+ { 2385315,2454213,-22631320,46603,-4437935,-15680415,656965,-7236665,24316168,-5253567 },
+ { 13741529,10911568,-33233417,-8603737,-20177830,-1033297,33040651,-13424532,-20729456,8321686 },
+ { 21060490,-2212744,15712757,-4336099,1639040,10656336,23845965,-11874838,-9984458,608372 },
+ },
+ {
+ { -13672732,-15087586,-10889693,-7557059,-6036909,11305547,1123968,-6780577,27229399,23887 },
+ { -23244140,-294205,-11744728,14712571,-29465699,-2029617,12797024,-6440308,-1633405,16678954 },
+ { -29500620,4770662,-16054387,14001338,7830047,9564805,-1508144,-4795045,-17169265,4904953 },
+ },
+ {
+ { 24059557,14617003,19037157,-15039908,19766093,-14906429,5169211,16191880,2128236,-4326833 },
+ { -16981152,4124966,-8540610,-10653797,30336522,-14105247,-29806336,916033,-6882542,-2986532 },
+ { -22630907,12419372,-7134229,-7473371,-16478904,16739175,285431,2763829,15736322,4143876 },
+ },
+ {
+ { 2379352,11839345,-4110402,-5988665,11274298,794957,212801,-14594663,23527084,-16458268 },
+ { 33431127,-11130478,-17838966,-15626900,8909499,8376530,-32625340,4087881,-15188911,-14416214 },
+ { 1767683,7197987,-13205226,-2022635,-13091350,448826,5799055,4357868,-4774191,-16323038 },
+ },
+},
+{
+ {
+ { 6721966,13833823,-23523388,-1551314,26354293,-11863321,23365147,-3949732,7390890,2759800 },
+ { 4409041,2052381,23373853,10530217,7676779,-12885954,21302353,-4264057,1244380,-12919645 },
+ { -4421239,7169619,4982368,-2957590,30256825,-2777540,14086413,9208236,15886429,16489664 },
+ },
+ {
+ { 1996075,10375649,14346367,13311202,-6874135,-16438411,-13693198,398369,-30606455,-712933 },
+ { -25307465,9795880,-2777414,14878809,-33531835,14780363,13348553,12076947,-30836462,5113182 },
+ { -17770784,11797796,31950843,13929123,-25888302,12288344,-30341101,-7336386,13847711,5387222 },
+ },
+ {
+ { -18582163,-3416217,17824843,-2340966,22744343,-10442611,8763061,3617786,-19600662,10370991 },
+ { 20246567,-14369378,22358229,-543712,18507283,-10413996,14554437,-8746092,32232924,16763880 },
+ { 9648505,10094563,26416693,14745928,-30374318,-6472621,11094161,15689506,3140038,-16510092 },
+ },
+ {
+ { -16160072,5472695,31895588,4744994,8823515,10365685,-27224800,9448613,-28774454,366295 },
+ { 19153450,11523972,-11096490,-6503142,-24647631,5420647,28344573,8041113,719605,11671788 },
+ { 8678025,2694440,-6808014,2517372,4964326,11152271,-15432916,-15266516,27000813,-10195553 },
+ },
+ {
+ { -15157904,7134312,8639287,-2814877,-7235688,10421742,564065,5336097,6750977,-14521026 },
+ { 11836410,-3979488,26297894,16080799,23455045,15735944,1695823,-8819122,8169720,16220347 },
+ { -18115838,8653647,17578566,-6092619,-8025777,-16012763,-11144307,-2627664,-5990708,-14166033 },
+ },
+ {
+ { -23308498,-10968312,15213228,-10081214,-30853605,-11050004,27884329,2847284,2655861,1738395 },
+ { -27537433,-14253021,-25336301,-8002780,-9370762,8129821,21651608,-3239336,-19087449,-11005278 },
+ { 1533110,3437855,23735889,459276,29970501,11335377,26030092,5821408,10478196,8544890 },
+ },
+ {
+ { 32173121,-16129311,24896207,3921497,22579056,-3410854,19270449,12217473,17789017,-3395995 },
+ { -30552961,-2228401,-15578829,-10147201,13243889,517024,15479401,-3853233,30460520,1052596 },
+ { -11614875,13323618,32618793,8175907,-15230173,12596687,27491595,-4612359,3179268,-9478891 },
+ },
+ {
+ { 31947069,-14366651,-4640583,-15339921,-15125977,-6039709,-14756777,-16411740,19072640,-9511060 },
+ { 11685058,11822410,3158003,-13952594,33402194,-4165066,5977896,-5215017,473099,5040608 },
+ { -20290863,8198642,-27410132,11602123,1290375,-2799760,28326862,1721092,-19558642,-3131606 },
+ },
+},
+{
+ {
+ { 7881532,10687937,7578723,7738378,-18951012,-2553952,21820786,8076149,-27868496,11538389 },
+ { -19935666,3899861,18283497,-6801568,-15728660,-11249211,8754525,7446702,-5676054,5797016 },
+ { -11295600,-3793569,-15782110,-7964573,12708869,-8456199,2014099,-9050574,-2369172,-5877341 },
+ },
+ {
+ { -22472376,-11568741,-27682020,1146375,18956691,16640559,1192730,-3714199,15123619,10811505 },
+ { 14352098,-3419715,-18942044,10822655,32750596,4699007,-70363,15776356,-28886779,-11974553 },
+ { -28241164,-8072475,-4978962,-5315317,29416931,1847569,-20654173,-16484855,4714547,-9600655 },
+ },
+ {
+ { 15200332,8368572,19679101,15970074,-31872674,1959451,24611599,-4543832,-11745876,12340220 },
+ { 12876937,-10480056,33134381,6590940,-6307776,14872440,9613953,8241152,15370987,9608631 },
+ { -4143277,-12014408,8446281,-391603,4407738,13629032,-7724868,15866074,-28210621,-8814099 },
+ },
+ {
+ { 26660628,-15677655,8393734,358047,-7401291,992988,-23904233,858697,20571223,8420556 },
+ { 14620715,13067227,-15447274,8264467,14106269,15080814,33531827,12516406,-21574435,-12476749 },
+ { 236881,10476226,57258,-14677024,6472998,2466984,17258519,7256740,8791136,15069930 },
+ },
+ {
+ { 1276410,-9371918,22949635,-16322807,-23493039,-5702186,14711875,4874229,-30663140,-2331391 },
+ { 5855666,4990204,-13711848,7294284,-7804282,1924647,-1423175,-7912378,-33069337,9234253 },
+ { 20590503,-9018988,31529744,-7352666,-2706834,10650548,31559055,-11609587,18979186,13396066 },
+ },
+ {
+ { 24474287,4968103,22267082,4407354,24063882,-8325180,-18816887,13594782,33514650,7021958 },
+ { -11566906,-6565505,-21365085,15928892,-26158305,4315421,-25948728,-3916677,-21480480,12868082 },
+ { -28635013,13504661,19988037,-2132761,21078225,6443208,-21446107,2244500,-12455797,-8089383 },
+ },
+ {
+ { -30595528,13793479,-5852820,319136,-25723172,-6263899,33086546,8957937,-15233648,5540521 },
+ { -11630176,-11503902,-8119500,-7643073,2620056,1022908,-23710744,-1568984,-16128528,-14962807 },
+ { 23152971,775386,27395463,14006635,-9701118,4649512,1689819,892185,-11513277,-15205948 },
+ },
+ {
+ { 9770129,9586738,26496094,4324120,1556511,-3550024,27453819,4763127,-19179614,5867134 },
+ { -32765025,1927590,31726409,-4753295,23962434,-16019500,27846559,5931263,-29749703,-16108455 },
+ { 27461885,-2977536,22380810,1815854,-23033753,-3031938,7283490,-15148073,-19526700,7734629 },
+ },
+},
+{
+ {
+ { -8010264,-9590817,-11120403,6196038,29344158,-13430885,7585295,-3176626,18549497,15302069 },
+ { -32658337,-6171222,-7672793,-11051681,6258878,13504381,10458790,-6418461,-8872242,8424746 },
+ { 24687205,8613276,-30667046,-3233545,1863892,-1830544,19206234,7134917,-11284482,-828919 },
+ },
+ {
+ { 11334899,-9218022,8025293,12707519,17523892,-10476071,10243738,-14685461,-5066034,16498837 },
+ { 8911542,6887158,-9584260,-6958590,11145641,-9543680,17303925,-14124238,6536641,10543906 },
+ { -28946384,15479763,-17466835,568876,-1497683,11223454,-2669190,-16625574,-27235709,8876771 },
+ },
+ {
+ { -25742899,-12566864,-15649966,-846607,-33026686,-796288,-33481822,15824474,-604426,-9039817 },
+ { 10330056,70051,7957388,-9002667,9764902,15609756,27698697,-4890037,1657394,3084098 },
+ { 10477963,-7470260,12119566,-13250805,29016247,-5365589,31280319,14396151,-30233575,15272409 },
+ },
+ {
+ { -12288309,3169463,28813183,16658753,25116432,-5630466,-25173957,-12636138,-25014757,1950504 },
+ { -26180358,9489187,11053416,-14746161,-31053720,5825630,-8384306,-8767532,15341279,8373727 },
+ { 28685821,7759505,-14378516,-12002860,-31971820,4079242,298136,-10232602,-2878207,15190420 },
+ },
+ {
+ { -32932876,13806336,-14337485,-15794431,-24004620,10940928,8669718,2742393,-26033313,-6875003 },
+ { -1580388,-11729417,-25979658,-11445023,-17411874,-10912854,9291594,-16247779,-12154742,6048605 },
+ { -30305315,14843444,1539301,11864366,20201677,1900163,13934231,5128323,11213262,9168384 },
+ },
+ {
+ { -26280513,11007847,19408960,-940758,-18592965,-4328580,-5088060,-11105150,20470157,-16398701 },
+ { -23136053,9282192,14855179,-15390078,-7362815,-14408560,-22783952,14461608,14042978,5230683 },
+ { 29969567,-2741594,-16711867,-8552442,9175486,-2468974,21556951,3506042,-5933891,-12449708 },
+ },
+ {
+ { -3144746,8744661,19704003,4581278,-20430686,6830683,-21284170,8971513,-28539189,15326563 },
+ { -19464629,10110288,-17262528,-3503892,-23500387,1355669,-15523050,15300988,-20514118,9168260 },
+ { -5353335,4488613,-23803248,16314347,7780487,-15638939,-28948358,9601605,33087103,-9011387 },
+ },
+ {
+ { -19443170,-15512900,-20797467,-12445323,-29824447,10229461,-27444329,-15000531,-5996870,15664672 },
+ { 23294591,-16632613,-22650781,-8470978,27844204,11461195,13099750,-2460356,18151676,13417686 },
+ { -24722913,-4176517,-31150679,5988919,-26858785,6685065,1661597,-12551441,15271676,-15452665 },
+ },
+},
+{
+ {
+ { 11433042,-13228665,8239631,-5279517,-1985436,-725718,-18698764,2167544,-6921301,-13440182 },
+ { -31436171,15575146,30436815,12192228,-22463353,9395379,-9917708,-8638997,12215110,12028277 },
+ { 14098400,6555944,23007258,5757252,-15427832,-12950502,30123440,4617780,-16900089,-655628 },
+ },
+ {
+ { -4026201,-15240835,11893168,13718664,-14809462,1847385,-15819999,10154009,23973261,-12684474 },
+ { -26531820,-3695990,-1908898,2534301,-31870557,-16550355,18341390,-11419951,32013174,-10103539 },
+ { -25479301,10876443,-11771086,-14625140,-12369567,1838104,21911214,6354752,4425632,-837822 },
+ },
+ {
+ { -10433389,-14612966,22229858,-3091047,-13191166,776729,-17415375,-12020462,4725005,14044970 },
+ { 19268650,-7304421,1555349,8692754,-21474059,-9910664,6347390,-1411784,-19522291,-16109756 },
+ { -24864089,12986008,-10898878,-5558584,-11312371,-148526,19541418,8180106,9282262,10282508 },
+ },
+ {
+ { -26205082,4428547,-8661196,-13194263,4098402,-14165257,15522535,8372215,5542595,-10702683 },
+ { -10562541,14895633,26814552,-16673850,-17480754,-2489360,-2781891,6993761,-18093885,10114655 },
+ { -20107055,-929418,31422704,10427861,-7110749,6150669,-29091755,-11529146,25953725,-106158 },
+ },
+ {
+ { -4234397,-8039292,-9119125,3046000,2101609,-12607294,19390020,6094296,-3315279,12831125 },
+ { -15998678,7578152,5310217,14408357,-33548620,-224739,31575954,6326196,7381791,-2421839 },
+ { -20902779,3296811,24736065,-16328389,18374254,7318640,6295303,8082724,-15362489,12339664 },
+ },
+ {
+ { 27724736,2291157,6088201,-14184798,1792727,5857634,13848414,15768922,25091167,14856294 },
+ { -18866652,8331043,24373479,8541013,-701998,-9269457,12927300,-12695493,-22182473,-9012899 },
+ { -11423429,-5421590,11632845,3405020,30536730,-11674039,-27260765,13866390,30146206,9142070 },
+ },
+ {
+ { 3924129,-15307516,-13817122,-10054960,12291820,-668366,-27702774,9326384,-8237858,4171294 },
+ { -15921940,16037937,6713787,16606682,-21612135,2790944,26396185,3731949,345228,-5462949 },
+ { -21327538,13448259,25284571,1143661,20614966,-8849387,2031539,-12391231,-16253183,-13582083 },
+ },
+ {
+ { 31016211,-16722429,26371392,-14451233,-5027349,14854137,17477601,3842657,28012650,-16405420 },
+ { -5075835,9368966,-8562079,-4600902,-15249953,6970560,-9189873,16292057,-8867157,3507940 },
+ { 29439664,3537914,23333589,6997794,-17555561,-11018068,-15209202,-15051267,-9164929,6580396 },
+ },
+},
+{
+ {
+ { -12185861,-7679788,16438269,10826160,-8696817,-6235611,17860444,-9273846,-2095802,9304567 },
+ { 20714564,-4336911,29088195,7406487,11426967,-5095705,14792667,-14608617,5289421,-477127 },
+ { -16665533,-10650790,-6160345,-13305760,9192020,-1802462,17271490,12349094,26939669,-3752294 },
+ },
+ {
+ { -12889898,9373458,31595848,16374215,21471720,13221525,-27283495,-12348559,-3698806,117887 },
+ { 22263325,-6560050,3984570,-11174646,-15114008,-566785,28311253,5358056,-23319780,541964 },
+ { 16259219,3261970,2309254,-15534474,-16885711,-4581916,24134070,-16705829,-13337066,-13552195 },
+ },
+ {
+ { 9378160,-13140186,-22845982,-12745264,28198281,-7244098,-2399684,-717351,690426,14876244 },
+ { 24977353,-314384,-8223969,-13465086,28432343,-1176353,-13068804,-12297348,-22380984,6618999 },
+ { -1538174,11685646,12944378,13682314,-24389511,-14413193,8044829,-13817328,32239829,-5652762 },
+ },
+ {
+ { -18603066,4762990,-926250,8885304,-28412480,-3187315,9781647,-10350059,32779359,5095274 },
+ { -33008130,-5214506,-32264887,-3685216,9460461,-9327423,-24601656,14506724,21639561,-2630236 },
+ { -16400943,-13112215,25239338,15531969,3987758,-4499318,-1289502,-6863535,17874574,558605 },
+ },
+ {
+ { -13600129,10240081,9171883,16131053,-20869254,9599700,33499487,5080151,2085892,5119761 },
+ { -22205145,-2519528,-16381601,414691,-25019550,2170430,30634760,-8363614,-31999993,-5759884 },
+ { -6845704,15791202,8550074,-1312654,29928809,-12092256,27534430,-7192145,-22351378,12961482 },
+ },
+ {
+ { -24492060,-9570771,10368194,11582341,-23397293,-2245287,16533930,8206996,-30194652,-5159638 },
+ { -11121496,-3382234,2307366,6362031,-135455,8868177,-16835630,7031275,7589640,8945490 },
+ { -32152748,8917967,6661220,-11677616,-1192060,-15793393,7251489,-11182180,24099109,-14456170 },
+ },
+ {
+ { 5019558,-7907470,4244127,-14714356,-26933272,6453165,-19118182,-13289025,-6231896,-10280736 },
+ { 10853594,10721687,26480089,5861829,-22995819,1972175,-1866647,-10557898,-3363451,-6441124 },
+ { -17002408,5906790,221599,-6563147,7828208,-13248918,24362661,-2008168,-13866408,7421392 },
+ },
+ {
+ { 8139927,-6546497,32257646,-5890546,30375719,1886181,-21175108,15441252,28826358,-4123029 },
+ { 6267086,9695052,7709135,-16603597,-32869068,-1886135,14795160,-7840124,13746021,-1742048 },
+ { 28584902,7787108,-6732942,-15050729,22846041,-7571236,-3181936,-363524,4771362,-8419958 },
+ },
+},
+{
+ {
+ { 24949256,6376279,-27466481,-8174608,-18646154,-9930606,33543569,-12141695,3569627,11342593 },
+ { 26514989,4740088,27912651,3697550,19331575,-11472339,6809886,4608608,7325975,-14801071 },
+ { -11618399,-14554430,-24321212,7655128,-1369274,5214312,-27400540,10258390,-17646694,-8186692 },
+ },
+ {
+ { 11431204,15823007,26570245,14329124,18029990,4796082,-31446179,15580664,9280358,-3973687 },
+ { -160783,-10326257,-22855316,-4304997,-20861367,-13621002,-32810901,-11181622,-15545091,4387441 },
+ { -20799378,12194512,3937617,-5805892,-27154820,9340370,-24513992,8548137,20617071,-7482001 },
+ },
+ {
+ { -938825,-3930586,-8714311,16124718,24603125,-6225393,-13775352,-11875822,24345683,10325460 },
+ { -19855277,-1568885,-22202708,8714034,14007766,6928528,16318175,-1010689,4766743,3552007 },
+ { -21751364,-16730916,1351763,-803421,-4009670,3950935,3217514,14481909,10988822,-3994762 },
+ },
+ {
+ { 15564307,-14311570,3101243,5684148,30446780,-8051356,12677127,-6505343,-8295852,13296005 },
+ { -9442290,6624296,-30298964,-11913677,-4670981,-2057379,31521204,9614054,-30000824,12074674 },
+ { 4771191,-135239,14290749,-13089852,27992298,14998318,-1413936,-1556716,29832613,-16391035 },
+ },
+ {
+ { 7064884,-7541174,-19161962,-5067537,-18891269,-2912736,25825242,5293297,-27122660,13101590 },
+ { -2298563,2439670,-7466610,1719965,-27267541,-16328445,32512469,-5317593,-30356070,-4190957 },
+ { -30006540,10162316,-33180176,3981723,-16482138,-13070044,14413974,9515896,19568978,9628812 },
+ },
+ {
+ { 33053803,199357,15894591,1583059,27380243,-4580435,-17838894,-6106839,-6291786,3437740 },
+ { -18978877,3884493,19469877,12726490,15913552,13614290,-22961733,70104,7463304,4176122 },
+ { -27124001,10659917,11482427,-16070381,12771467,-6635117,-32719404,-5322751,24216882,5944158 },
+ },
+ {
+ { 8894125,7450974,-2664149,-9765752,-28080517,-12389115,19345746,14680796,11632993,5847885 },
+ { 26942781,-2315317,9129564,-4906607,26024105,11769399,-11518837,6367194,-9727230,4782140 },
+ { 19916461,-4828410,-22910704,-11414391,25606324,-5972441,33253853,8220911,6358847,-1873857 },
+ },
+ {
+ { 801428,-2081702,16569428,11065167,29875704,96627,7908388,-4480480,-13538503,1387155 },
+ { 19646058,5720633,-11416706,12814209,11607948,12749789,14147075,15156355,-21866831,11835260 },
+ { 19299512,1155910,28703737,14890794,2925026,7269399,26121523,15467869,-26560550,5052483 },
+ },
+},
+{
+ {
+ { -3017432,10058206,1980837,3964243,22160966,12322533,-6431123,-12618185,12228557,-7003677 },
+ { 32944382,14922211,-22844894,5188528,21913450,-8719943,4001465,13238564,-6114803,8653815 },
+ { 22865569,-4652735,27603668,-12545395,14348958,8234005,24808405,5719875,28483275,2841751 },
+ },
+ {
+ { -16420968,-1113305,-327719,-12107856,21886282,-15552774,-1887966,-315658,19932058,-12739203 },
+ { -11656086,10087521,-8864888,-5536143,-19278573,-3055912,3999228,13239134,-4777469,-13910208 },
+ { 1382174,-11694719,17266790,9194690,-13324356,9720081,20403944,11284705,-14013818,3093230 },
+ },
+ {
+ { 16650921,-11037932,-1064178,1570629,-8329746,7352753,-302424,16271225,-24049421,-6691850 },
+ { -21911077,-5927941,-4611316,-5560156,-31744103,-10785293,24123614,15193618,-21652117,-16739389 },
+ { -9935934,-4289447,-25279823,4372842,2087473,10399484,31870908,14690798,17361620,11864968 },
+ },
+ {
+ { -11307610,6210372,13206574,5806320,-29017692,-13967200,-12331205,-7486601,-25578460,-16240689 },
+ { 14668462,-12270235,26039039,15305210,25515617,4542480,10453892,6577524,9145645,-6443880 },
+ { 5974874,3053895,-9433049,-10385191,-31865124,3225009,-7972642,3936128,-5652273,-3050304 },
+ },
+ {
+ { 30625386,-4729400,-25555961,-12792866,-20484575,7695099,17097188,-16303496,-27999779,1803632 },
+ { -3553091,9865099,-5228566,4272701,-5673832,-16689700,14911344,12196514,-21405489,7047412 },
+ { 20093277,9920966,-11138194,-5343857,13161587,12044805,-32856851,4124601,-32343828,-10257566 },
+ },
+ {
+ { -20788824,14084654,-13531713,7842147,19119038,-13822605,4752377,-8714640,-21679658,2288038 },
+ { -26819236,-3283715,29965059,3039786,-14473765,2540457,29457502,14625692,-24819617,12570232 },
+ { -1063558,-11551823,16920318,12494842,1278292,-5869109,-21159943,-3498680,-11974704,4724943 },
+ },
+ {
+ { 17960970,-11775534,-4140968,-9702530,-8876562,-1410617,-12907383,-8659932,-29576300,1903856 },
+ { 23134274,-14279132,-10681997,-1611936,20684485,15770816,-12989750,3190296,26955097,14109738 },
+ { 15308788,5320727,-30113809,-14318877,22902008,7767164,29425325,-11277562,31960942,11934971 },
+ },
+ {
+ { -27395711,8435796,4109644,12222639,-24627868,14818669,20638173,4875028,10491392,1379718 },
+ { -13159415,9197841,3875503,-8936108,-1383712,-5879801,33518459,16176658,21432314,12180697 },
+ { -11787308,11500838,13787581,-13832590,-22430679,10140205,1465425,12689540,-10301319,-13872883 },
+ },
+},
+{
+ {
+ { 5414091,-15386041,-21007664,9643570,12834970,1186149,-2622916,-1342231,26128231,6032912 },
+ { -26337395,-13766162,32496025,-13653919,17847801,-12669156,3604025,8316894,-25875034,-10437358 },
+ { 3296484,6223048,24680646,-12246460,-23052020,5903205,-8862297,-4639164,12376617,3188849 },
+ },
+ {
+ { 29190488,-14659046,27549113,-1183516,3520066,-10697301,32049515,-7309113,-16109234,-9852307 },
+ { -14744486,-9309156,735818,-598978,-20407687,-5057904,25246078,-15795669,18640741,-960977 },
+ { -6928835,-16430795,10361374,5642961,4910474,12345252,-31638386,-494430,10530747,1053335 },
+ },
+ {
+ { -29265967,-14186805,-13538216,-12117373,-19457059,-10655384,-31462369,-2948985,24018831,15026644 },
+ { -22592535,-3145277,-2289276,5953843,-13440189,9425631,25310643,13003497,-2314791,-15145616 },
+ { -27419985,-603321,-8043984,-1669117,-26092265,13987819,-27297622,187899,-23166419,-2531735 },
+ },
+ {
+ { -21744398,-13810475,1844840,5021428,-10434399,-15911473,9716667,16266922,-5070217,726099 },
+ { 29370922,-6053998,7334071,-15342259,9385287,2247707,-13661962,-4839461,30007388,-15823341 },
+ { -936379,16086691,23751945,-543318,-1167538,-5189036,9137109,730663,9835848,4555336 },
+ },
+ {
+ { -23376435,1410446,-22253753,-12899614,30867635,15826977,17693930,544696,-11985298,12422646 },
+ { 31117226,-12215734,-13502838,6561947,-9876867,-12757670,-5118685,-4096706,29120153,13924425 },
+ { -17400879,-14233209,19675799,-2734756,-11006962,-5858820,-9383939,-11317700,7240931,-237388 },
+ },
+ {
+ { -31361739,-11346780,-15007447,-5856218,-22453340,-12152771,1222336,4389483,3293637,-15551743 },
+ { -16684801,-14444245,11038544,11054958,-13801175,-3338533,-24319580,7733547,12796905,-6335822 },
+ { -8759414,-10817836,-25418864,10783769,-30615557,-9746811,-28253339,3647836,3222231,-11160462 },
+ },
+ {
+ { 18606113,1693100,-25448386,-15170272,4112353,10045021,23603893,-2048234,-7550776,2484985 },
+ { 9255317,-3131197,-12156162,-1004256,13098013,-9214866,16377220,-2102812,-19802075,-3034702 },
+ { -22729289,7496160,-5742199,11329249,19991973,-3347502,-31718148,9936966,-30097688,-10618797 },
+ },
+ {
+ { 21878590,-5001297,4338336,13643897,-3036865,13160960,19708896,5415497,-7360503,-4109293 },
+ { 27736861,10103576,12500508,8502413,-3413016,-9633558,10436918,-1550276,-23659143,-8132100 },
+ { 19492550,-12104365,-29681976,-852630,-3208171,12403437,30066266,8367329,13243957,8709688 },
+ },
+},
+{
+ {
+ { 12015105,2801261,28198131,10151021,24818120,-4743133,-11194191,-5645734,5150968,7274186 },
+ { 2831366,-12492146,1478975,6122054,23825128,-12733586,31097299,6083058,31021603,-9793610 },
+ { -2529932,-2229646,445613,10720828,-13849527,-11505937,-23507731,16354465,15067285,-14147707 },
+ },
+ {
+ { 7840942,14037873,-33364863,15934016,-728213,-3642706,21403988,1057586,-19379462,-12403220 },
+ { 915865,-16469274,15608285,-8789130,-24357026,6060030,-17371319,8410997,-7220461,16527025 },
+ { 32922597,-556987,20336074,-16184568,10903705,-5384487,16957574,52992,23834301,6588044 },
+ },
+ {
+ { 32752030,11232950,3381995,-8714866,22652988,-10744103,17159699,16689107,-20314580,-1305992 },
+ { -4689649,9166776,-25710296,-10847306,11576752,12733943,7924251,-2752281,1976123,-7249027 },
+ { 21251222,16309901,-2983015,-6783122,30810597,12967303,156041,-3371252,12331345,-8237197 },
+ },
+ {
+ { 8651614,-4477032,-16085636,-4996994,13002507,2950805,29054427,-5106970,10008136,-4667901 },
+ { 31486080,15114593,-14261250,12951354,14369431,-7387845,16347321,-13662089,8684155,-10532952 },
+ { 19443825,11385320,24468943,-9659068,-23919258,2187569,-26263207,-6086921,31316348,14219878 },
+ },
+ {
+ { -28594490,1193785,32245219,11392485,31092169,15722801,27146014,6992409,29126555,9207390 },
+ { 32382935,1110093,18477781,11028262,-27411763,-7548111,-4980517,10843782,-7957600,-14435730 },
+ { 2814918,7836403,27519878,-7868156,-20894015,-11553689,-21494559,8550130,28346258,1994730 },
+ },
+ {
+ { -19578299,8085545,-14000519,-3948622,2785838,-16231307,-19516951,7174894,22628102,8115180 },
+ { -30405132,955511,-11133838,-15078069,-32447087,-13278079,-25651578,3317160,-9943017,930272 },
+ { -15303681,-6833769,28856490,1357446,23421993,1057177,24091212,-1388970,-22765376,-10650715 },
+ },
+ {
+ { -22751231,-5303997,-12907607,-12768866,-15811511,-7797053,-14839018,-16554220,-1867018,8398970 },
+ { -31969310,2106403,-4736360,1362501,12813763,16200670,22981545,-6291273,18009408,-15772772 },
+ { -17220923,-9545221,-27784654,14166835,29815394,7444469,29551787,-3727419,19288549,1325865 },
+ },
+ {
+ { 15100157,-15835752,-23923978,-1005098,-26450192,15509408,12376730,-3479146,33166107,-8042750 },
+ { 20909231,13023121,-9209752,16251778,-5778415,-8094914,12412151,10018715,2213263,-13878373 },
+ { 32529814,-11074689,30361439,-16689753,-9135940,1513226,22922121,6382134,-5766928,8371348 },
+ },
+},
+{
+ {
+ { 9923462,11271500,12616794,3544722,-29998368,-1721626,12891687,-8193132,-26442943,10486144 },
+ { -22597207,-7012665,8587003,-8257861,4084309,-12970062,361726,2610596,-23921530,-11455195 },
+ { 5408411,-1136691,-4969122,10561668,24145918,14240566,31319731,-4235541,19985175,-3436086 },
+ },
+ {
+ { -13994457,16616821,14549246,3341099,32155958,13648976,-17577068,8849297,65030,8370684 },
+ { -8320926,-12049626,31204563,5839400,-20627288,-1057277,-19442942,6922164,12743482,-9800518 },
+ { -2361371,12678785,28815050,4759974,-23893047,4884717,23783145,11038569,18800704,255233 },
+ },
+ {
+ { -5269658,-1773886,13957886,7990715,23132995,728773,13393847,9066957,19258688,-14753793 },
+ { -2936654,-10827535,-10432089,14516793,-3640786,4372541,-31934921,2209390,-1524053,2055794 },
+ { 580882,16705327,5468415,-2683018,-30926419,-14696000,-7203346,-8994389,-30021019,7394435 },
+ },
+ {
+ { 23838809,1822728,-15738443,15242727,8318092,-3733104,-21672180,-3492205,-4821741,14799921 },
+ { 13345610,9759151,3371034,-16137791,16353039,8577942,31129804,13496856,-9056018,7402518 },
+ { 2286874,-4435931,-20042458,-2008336,-13696227,5038122,11006906,-15760352,8205061,1607563 },
+ },
+ {
+ { 14414086,-8002132,3331830,-3208217,22249151,-5594188,18364661,-2906958,30019587,-9029278 },
+ { -27688051,1585953,-10775053,931069,-29120221,-11002319,-14410829,12029093,9944378,8024 },
+ { 4368715,-3709630,29874200,-15022983,-20230386,-11410704,-16114594,-999085,-8142388,5640030 },
+ },
+ {
+ { 10299610,13746483,11661824,16234854,7630238,5998374,9809887,-16694564,15219798,-14327783 },
+ { 27425505,-5719081,3055006,10660664,23458024,595578,-15398605,-1173195,-18342183,9742717 },
+ { 6744077,2427284,26042789,2720740,-847906,1118974,32324614,7406442,12420155,1994844 },
+ },
+ {
+ { 14012521,-5024720,-18384453,-9578469,-26485342,-3936439,-13033478,-10909803,24319929,-6446333 },
+ { 16412690,-4507367,10772641,15929391,-17068788,-4658621,10555945,-10484049,-30102368,-4739048 },
+ { 22397382,-7767684,-9293161,-12792868,17166287,-9755136,-27333065,6199366,21880021,-12250760 },
+ },
+ {
+ { -4283307,5368523,-31117018,8163389,-30323063,3209128,16557151,8890729,8840445,4957760 },
+ { -15447727,709327,-6919446,-10870178,-29777922,6522332,-21720181,12130072,-14796503,5005757 },
+ { -2114751,-14308128,23019042,15765735,-25269683,6002752,10183197,-13239326,-16395286,-2176112 },
+ },
+},
+{
+ {
+ { -19025756,1632005,13466291,-7995100,-23640451,16573537,-32013908,-3057104,22208662,2000468 },
+ { 3065073,-1412761,-25598674,-361432,-17683065,-5703415,-8164212,11248527,-3691214,-7414184 },
+ { 10379208,-6045554,8877319,1473647,-29291284,-12507580,16690915,2553332,-3132688,16400289 },
+ },
+ {
+ { 15716668,1254266,-18472690,7446274,-8448918,6344164,-22097271,-7285580,26894937,9132066 },
+ { 24158887,12938817,11085297,-8177598,-28063478,-4457083,-30576463,64452,-6817084,-2692882 },
+ { 13488534,7794716,22236231,5989356,25426474,-12578208,2350710,-3418511,-4688006,2364226 },
+ },
+ {
+ { 16335052,9132434,25640582,6678888,1725628,8517937,-11807024,-11697457,15445875,-7798101 },
+ { 29004207,-7867081,28661402,-640412,-12794003,-7943086,31863255,-4135540,-278050,-15759279 },
+ { -6122061,-14866665,-28614905,14569919,-10857999,-3591829,10343412,-6976290,-29828287,-10815811 },
+ },
+ {
+ { 27081650,3463984,14099042,-4517604,1616303,-6205604,29542636,15372179,17293797,960709 },
+ { 20263915,11434237,-5765435,11236810,13505955,-10857102,-16111345,6493122,-19384511,7639714 },
+ { -2830798,-14839232,25403038,-8215196,-8317012,-16173699,18006287,-16043750,29994677,-15808121 },
+ },
+ {
+ { 9769828,5202651,-24157398,-13631392,-28051003,-11561624,-24613141,-13860782,-31184575,709464 },
+ { 12286395,13076066,-21775189,-1176622,-25003198,4057652,-32018128,-8890874,16102007,13205847 },
+ { 13733362,5599946,10557076,3195751,-5557991,8536970,-25540170,8525972,10151379,10394400 },
+ },
+ {
+ { 4024660,-16137551,22436262,12276534,-9099015,-2686099,19698229,11743039,-33302334,8934414 },
+ { -15879800,-4525240,-8580747,-2934061,14634845,-698278,-9449077,3137094,-11536886,11721158 },
+ { 17555939,-5013938,8268606,2331751,-22738815,9761013,9319229,8835153,-9205489,-1280045 },
+ },
+ {
+ { -461409,-7830014,20614118,16688288,-7514766,-4807119,22300304,505429,6108462,-6183415 },
+ { -5070281,12367917,-30663534,3234473,32617080,-8422642,29880583,-13483331,-26898490,-7867459 },
+ { -31975283,5726539,26934134,10237677,-3173717,-605053,24199304,3795095,7592688,-14992079 },
+ },
+ {
+ { 21594432,-14964228,17466408,-4077222,32537084,2739898,6407723,12018833,-28256052,4298412 },
+ { -20650503,-11961496,-27236275,570498,3767144,-1717540,13891942,-1569194,13717174,10805743 },
+ { -14676630,-15644296,15287174,11927123,24177847,-8175568,-796431,14860609,-26938930,-5863836 },
+ },
+},
+{
+ {
+ { 12962541,5311799,-10060768,11658280,18855286,-7954201,13286263,-12808704,-4381056,9882022 },
+ { 18512079,11319350,-20123124,15090309,18818594,5271736,-22727904,3666879,-23967430,-3299429 },
+ { -6789020,-3146043,16192429,13241070,15898607,-14206114,-10084880,-6661110,-2403099,5276065 },
+ },
+ {
+ { 30169808,-5317648,26306206,-11750859,27814964,7069267,7152851,3684982,1449224,13082861 },
+ { 10342826,3098505,2119311,193222,25702612,12233820,23697382,15056736,-21016438,-8202000 },
+ { -33150110,3261608,22745853,7948688,19370557,-15177665,-26171976,6482814,-10300080,-11060101 },
+ },
+ {
+ { 32869458,-5408545,25609743,15678670,-10687769,-15471071,26112421,2521008,-22664288,6904815 },
+ { 29506923,4457497,3377935,-9796444,-30510046,12935080,1561737,3841096,-29003639,-6657642 },
+ { 10340844,-6630377,-18656632,-2278430,12621151,-13339055,30878497,-11824370,-25584551,5181966 },
+ },
+ {
+ { 25940115,-12658025,17324188,-10307374,-8671468,15029094,24396252,-16450922,-2322852,-12388574 },
+ { -21765684,9916823,-1300409,4079498,-1028346,11909559,1782390,12641087,20603771,-6561742 },
+ { -18882287,-11673380,24849422,11501709,13161720,-4768874,1925523,11914390,4662781,7820689 },
+ },
+ {
+ { 12241050,-425982,8132691,9393934,32846760,-1599620,29749456,12172924,16136752,15264020 },
+ { -10349955,-14680563,-8211979,2330220,-17662549,-14545780,10658213,6671822,19012087,3772772 },
+ { 3753511,-3421066,10617074,2028709,14841030,-6721664,28718732,-15762884,20527771,12988982 },
+ },
+ {
+ { -14822485,-5797269,-3707987,12689773,-898983,-10914866,-24183046,-10564943,3299665,-12424953 },
+ { -16777703,-15253301,-9642417,4978983,3308785,8755439,6943197,6461331,-25583147,8991218 },
+ { -17226263,1816362,-1673288,-6086439,31783888,-8175991,-32948145,7417950,-30242287,1507265 },
+ },
+ {
+ { 29692663,6829891,-10498800,4334896,20945975,-11906496,-28887608,8209391,14606362,-10647073 },
+ { -3481570,8707081,32188102,5672294,22096700,1711240,-33020695,9761487,4170404,-2085325 },
+ { -11587470,14855945,-4127778,-1531857,-26649089,15084046,22186522,16002000,-14276837,-8400798 },
+ },
+ {
+ { -4811456,13761029,-31703877,-2483919,-3312471,7869047,-7113572,-9620092,13240845,10965870 },
+ { -7742563,-8256762,-14768334,-13656260,-23232383,12387166,4498947,14147411,29514390,4302863 },
+ { -13413405,-12407859,20757302,-13801832,14785143,8976368,-5061276,-2144373,17846988,-13971927 },
+ },
+},
+{
+ {
+ { -2244452,-754728,-4597030,-1066309,-6247172,1455299,-21647728,-9214789,-5222701,12650267 },
+ { -9906797,-16070310,21134160,12198166,-27064575,708126,387813,13770293,-19134326,10958663 },
+ { 22470984,12369526,23446014,-5441109,-21520802,-9698723,-11772496,-11574455,-25083830,4271862 },
+ },
+ {
+ { -25169565,-10053642,-19909332,15361595,-5984358,2159192,75375,-4278529,-32526221,8469673 },
+ { 15854970,4148314,-8893890,7259002,11666551,13824734,-30531198,2697372,24154791,-9460943 },
+ { 15446137,-15806644,29759747,14019369,30811221,-9610191,-31582008,12840104,24913809,9815020 },
+ },
+ {
+ { -4709286,-5614269,-31841498,-12288893,-14443537,10799414,-9103676,13438769,18735128,9466238 },
+ { 11933045,9281483,5081055,-5183824,-2628162,-4905629,-7727821,-10896103,-22728655,16199064 },
+ { 14576810,379472,-26786533,-8317236,-29426508,-10812974,-102766,1876699,30801119,2164795 },
+ },
+ {
+ { 15995086,3199873,13672555,13712240,-19378835,-4647646,-13081610,-15496269,-13492807,1268052 },
+ { -10290614,-3659039,-3286592,10948818,23037027,3794475,-3470338,-12600221,-17055369,3565904 },
+ { 29210088,-9419337,-5919792,-4952785,10834811,-13327726,-16512102,-10820713,-27162222,-14030531 },
+ },
+ {
+ { -13161890,15508588,16663704,-8156150,-28349942,9019123,-29183421,-3769423,2244111,-14001979 },
+ { -5152875,-3800936,-9306475,-6071583,16243069,14684434,-25673088,-16180800,13491506,4641841 },
+ { 10813417,643330,-19188515,-728916,30292062,-16600078,27548447,-7721242,14476989,-12767431 },
+ },
+ {
+ { 10292079,9984945,6481436,8279905,-7251514,7032743,27282937,-1644259,-27912810,12651324 },
+ { -31185513,-813383,22271204,11835308,10201545,15351028,17099662,3988035,21721536,-3148940 },
+ { 10202177,-6545839,-31373232,-9574638,-32150642,-8119683,-12906320,3852694,13216206,14842320 },
+ },
+ {
+ { -15815640,-10601066,-6538952,-7258995,-6984659,-6581778,-31500847,13765824,-27434397,9900184 },
+ { 14465505,-13833331,-32133984,-14738873,-27443187,12990492,33046193,15796406,-7051866,-8040114 },
+ { 30924417,-8279620,6359016,-12816335,16508377,9071735,-25488601,15413635,9524356,-7018878 },
+ },
+ {
+ { 12274201,-13175547,32627641,-1785326,6736625,13267305,5237659,-5109483,15663516,4035784 },
+ { -2951309,8903985,17349946,601635,-16432815,-4612556,-13732739,-15889334,-22258478,4659091 },
+ { -16916263,-4952973,-30393711,-15158821,20774812,15897498,5736189,15026997,-2178256,-13455585 },
+ },
+},
+{
+ {
+ { -8858980,-2219056,28571666,-10155518,-474467,-10105698,-3801496,278095,23440562,-290208 },
+ { 10226241,-5928702,15139956,120818,-14867693,5218603,32937275,11551483,-16571960,-7442864 },
+ { 17932739,-12437276,-24039557,10749060,11316803,7535897,22503767,5561594,-3646624,3898661 },
+ },
+ {
+ { 7749907,-969567,-16339731,-16464,-25018111,15122143,-1573531,7152530,21831162,1245233 },
+ { 26958459,-14658026,4314586,8346991,-5677764,11960072,-32589295,-620035,-30402091,-16716212 },
+ { -12165896,9166947,33491384,13673479,29787085,13096535,6280834,14587357,-22338025,13987525 },
+ },
+ {
+ { -24349909,7778775,21116000,15572597,-4833266,-5357778,-4300898,-5124639,-7469781,-2858068 },
+ { 9681908,-6737123,-31951644,13591838,-6883821,386950,31622781,6439245,-14581012,4091397 },
+ { -8426427,1470727,-28109679,-1596990,3978627,-5123623,-19622683,12092163,29077877,-14741988 },
+ },
+ {
+ { 5269168,-6859726,-13230211,-8020715,25932563,1763552,-5606110,-5505881,-20017847,2357889 },
+ { 32264008,-15407652,-5387735,-1160093,-2091322,-3946900,23104804,-12869908,5727338,189038 },
+ { 14609123,-8954470,-6000566,-16622781,-14577387,-7743898,-26745169,10942115,-25888931,-14884697 },
+ },
+ {
+ { 20513500,5557931,-15604613,7829531,26413943,-2019404,-21378968,7471781,13913677,-5137875 },
+ { -25574376,11967826,29233242,12948236,-6754465,4713227,-8940970,14059180,12878652,8511905 },
+ { -25656801,3393631,-2955415,-7075526,-2250709,9366908,-30223418,6812974,5568676,-3127656 },
+ },
+ {
+ { 11630004,12144454,2116339,13606037,27378885,15676917,-17408753,-13504373,-14395196,8070818 },
+ { 27117696,-10007378,-31282771,-5570088,1127282,12772488,-29845906,10483306,-11552749,-1028714 },
+ { 10637467,-5688064,5674781,1072708,-26343588,-6982302,-1683975,9177853,-27493162,15431203 },
+ },
+ {
+ { 20525145,10892566,-12742472,12779443,-29493034,16150075,-28240519,14943142,-15056790,-7935931 },
+ { -30024462,5626926,-551567,-9981087,753598,11981191,25244767,-3239766,-3356550,9594024 },
+ { -23752644,2636870,-5163910,-10103818,585134,7877383,11345683,-6492290,13352335,-10977084 },
+ },
+ {
+ { -1931799,-5407458,3304649,-12884869,17015806,-4877091,-29783850,-7752482,-13215537,-319204 },
+ { 20239939,6607058,6203985,3483793,-18386976,-779229,-20723742,15077870,-22750759,14523817 },
+ { 27406042,-6041657,27423596,-4497394,4996214,10002360,-28842031,-4545494,-30172742,-4805667 },
+ },
+},
+{
+ {
+ { 11374242,12660715,17861383,-12540833,10935568,1099227,-13886076,-9091740,-27727044,11358504 },
+ { -12730809,10311867,1510375,10778093,-2119455,-9145702,32676003,11149336,-26123651,4985768 },
+ { -19096303,341147,-6197485,-239033,15756973,-8796662,-983043,13794114,-19414307,-15621255 },
+ },
+ {
+ { 6490081,11940286,25495923,-7726360,8668373,-8751316,3367603,6970005,-1691065,-9004790 },
+ { 1656497,13457317,15370807,6364910,13605745,8362338,-19174622,-5475723,-16796596,-5031438 },
+ { -22273315,-13524424,-64685,-4334223,-18605636,-10921968,-20571065,-7007978,-99853,-10237333 },
+ },
+ {
+ { 17747465,10039260,19368299,-4050591,-20630635,-16041286,31992683,-15857976,-29260363,-5511971 },
+ { 31932027,-4986141,-19612382,16366580,22023614,88450,11371999,-3744247,4882242,-10626905 },
+ { 29796507,37186,19818052,10115756,-11829032,3352736,18551198,3272828,-5190932,-4162409 },
+ },
+ {
+ { 12501286,4044383,-8612957,-13392385,-32430052,5136599,-19230378,-3529697,330070,-3659409 },
+ { 6384877,2899513,17807477,7663917,-2358888,12363165,25366522,-8573892,-271295,12071499 },
+ { -8365515,-4042521,25133448,-4517355,-6211027,2265927,-32769618,1936675,-5159697,3829363 },
+ },
+ {
+ { 28425966,-5835433,-577090,-4697198,-14217555,6870930,7921550,-6567787,26333140,14267664 },
+ { -11067219,11871231,27385719,-10559544,-4585914,-11189312,10004786,-8709488,-21761224,8930324 },
+ { -21197785,-16396035,25654216,-1725397,12282012,11008919,1541940,4757911,-26491501,-16408940 },
+ },
+ {
+ { 13537262,-7759490,-20604840,10961927,-5922820,-13218065,-13156584,6217254,-15943699,13814990 },
+ { -17422573,15157790,18705543,29619,24409717,-260476,27361681,9257833,-1956526,-1776914 },
+ { -25045300,-10191966,15366585,15166509,-13105086,8423556,-29171540,12361135,-18685978,4578290 },
+ },
+ {
+ { 24579768,3711570,1342322,-11180126,-27005135,14124956,-22544529,14074919,21964432,8235257 },
+ { -6528613,-2411497,9442966,-5925588,12025640,-1487420,-2981514,-1669206,13006806,2355433 },
+ { -16304899,-13605259,-6632427,-5142349,16974359,-10911083,27202044,1719366,1141648,-12796236 },
+ },
+ {
+ { -12863944,-13219986,-8318266,-11018091,-6810145,-4843894,13475066,-3133972,32674895,13715045 },
+ { 11423335,-5468059,32344216,8962751,24989809,9241752,-13265253,16086212,-28740881,-15642093 },
+ { -1409668,12530728,-6368726,10847387,19531186,-14132160,-11709148,7791794,-27245943,4383347 },
+ },
+},
+{
+ {
+ { -28970898,5271447,-1266009,-9736989,-12455236,16732599,-4862407,-4906449,27193557,6245191 },
+ { -15193956,5362278,-1783893,2695834,4960227,12840725,23061898,3260492,22510453,8577507 },
+ { -12632451,11257346,-32692994,13548177,-721004,10879011,31168030,13952092,-29571492,-3635906 },
+ },
+ {
+ { 3877321,-9572739,32416692,5405324,-11004407,-13656635,3759769,11935320,5611860,8164018 },
+ { -16275802,14667797,15906460,12155291,-22111149,-9039718,32003002,-8832289,5773085,-8422109 },
+ { -23788118,-8254300,1950875,8937633,18686727,16459170,-905725,12376320,31632953,190926 },
+ },
+ {
+ { -24593607,-16138885,-8423991,13378746,14162407,6901328,-8288749,4508564,-25341555,-3627528 },
+ { 8884438,-5884009,6023974,10104341,-6881569,-4941533,18722941,-14786005,-1672488,827625 },
+ { -32720583,-16289296,-32503547,7101210,13354605,2659080,-1800575,-14108036,-24878478,1541286 },
+ },
+ {
+ { 2901347,-1117687,3880376,-10059388,-17620940,-3612781,-21802117,-3567481,20456845,-1885033 },
+ { 27019610,12299467,-13658288,-1603234,-12861660,-4861471,-19540150,-5016058,29439641,15138866 },
+ { 21536104,-6626420,-32447818,-10690208,-22408077,5175814,-5420040,-16361163,7779328,109896 },
+ },
+ {
+ { 30279744,14648750,-8044871,6425558,13639621,-743509,28698390,12180118,23177719,-554075 },
+ { 26572847,3405927,-31701700,12890905,-19265668,5335866,-6493768,2378492,4439158,-13279347 },
+ { -22716706,3489070,-9225266,-332753,18875722,-1140095,14819434,-12731527,-17717757,-5461437 },
+ },
+ {
+ { -5056483,16566551,15953661,3767752,-10436499,15627060,-820954,2177225,8550082,-15114165 },
+ { -18473302,16596775,-381660,15663611,22860960,15585581,-27844109,-3582739,-23260460,-8428588 },
+ { -32480551,15707275,-8205912,-5652081,29464558,2713815,-22725137,15860482,-21902570,1494193 },
+ },
+ {
+ { -19562091,-14087393,-25583872,-9299552,13127842,759709,21923482,16529112,8742704,12967017 },
+ { -28464899,1553205,32536856,-10473729,-24691605,-406174,-8914625,-2933896,-29903758,15553883 },
+ { 21877909,3230008,9881174,10539357,-4797115,2841332,11543572,14513274,19375923,-12647961 },
+ },
+ {
+ { 8832269,-14495485,13253511,5137575,5037871,4078777,24880818,-6222716,2862653,9455043 },
+ { 29306751,5123106,20245049,-14149889,9592566,8447059,-2077124,-2990080,15511449,4789663 },
+ { -20679756,7004547,8824831,-9434977,-4045704,-3750736,-5754762,108893,23513200,16652362 },
+ },
+},
+{
+ {
+ { -33256173,4144782,-4476029,-6579123,10770039,-7155542,-6650416,-12936300,-18319198,10212860 },
+ { 2756081,8598110,7383731,-6859892,22312759,-1105012,21179801,2600940,-9988298,-12506466 },
+ { -24645692,13317462,-30449259,-15653928,21365574,-10869657,11344424,864440,-2499677,-16710063 },
+ },
+ {
+ { -26432803,6148329,-17184412,-14474154,18782929,-275997,-22561534,211300,2719757,4940997 },
+ { -1323882,3911313,-6948744,14759765,-30027150,7851207,21690126,8518463,26699843,5276295 },
+ { -13149873,-6429067,9396249,365013,24703301,-10488939,1321586,149635,-15452774,7159369 },
+ },
+ {
+ { 9987780,-3404759,17507962,9505530,9731535,-2165514,22356009,8312176,22477218,-8403385 },
+ { 18155857,-16504990,19744716,9006923,15154154,-10538976,24256460,-4864995,-22548173,9334109 },
+ { 2986088,-4911893,10776628,-3473844,10620590,-7083203,-21413845,14253545,-22587149,536906 },
+ },
+ {
+ { 4377756,8115836,24567078,15495314,11625074,13064599,7390551,10589625,10838060,-15420424 },
+ { -19342404,867880,9277171,-3218459,-14431572,-1986443,19295826,-15796950,6378260,699185 },
+ { 7895026,4057113,-7081772,-13077756,-17886831,-323126,-716039,15693155,-5045064,-13373962 },
+ },
+ {
+ { -7737563,-5869402,-14566319,-7406919,11385654,13201616,31730678,-10962840,-3918636,-9669325 },
+ { 10188286,-15770834,-7336361,13427543,22223443,14896287,30743455,7116568,-21786507,5427593 },
+ { 696102,13206899,27047647,-10632082,15285305,-9853179,10798490,-4578720,19236243,12477404 },
+ },
+ {
+ { -11229439,11243796,-17054270,-8040865,-788228,-8167967,-3897669,11180504,-23169516,7733644 },
+ { 17800790,-14036179,-27000429,-11766671,23887827,3149671,23466177,-10538171,10322027,15313801 },
+ { 26246234,11968874,32263343,-5468728,6830755,-13323031,-15794704,-101982,-24449242,10890804 },
+ },
+ {
+ { -31365647,10271363,-12660625,-6267268,16690207,-13062544,-14982212,16484931,25180797,-5334884 },
+ { -586574,10376444,-32586414,-11286356,19801893,10997610,2276632,9482883,316878,13820577 },
+ { -9882808,-4510367,-2115506,16457136,-11100081,11674996,30756178,-7515054,30696930,-3712849 },
+ },
+ {
+ { 32988917,-9603412,12499366,7910787,-10617257,-11931514,-7342816,-9985397,-32349517,7392473 },
+ { -8855661,15927861,9866406,-3649411,-2396914,-16655781,-30409476,-9134995,25112947,-2926644 },
+ { -2504044,-436966,25621774,-5678772,15085042,-5479877,-24884878,-13526194,5537438,-13914319 },
+ },
+},
+{
+ {
+ { -11225584,2320285,-9584280,10149187,-33444663,5808648,-14876251,-1729667,31234590,6090599 },
+ { -9633316,116426,26083934,2897444,-6364437,-2688086,609721,15878753,-6970405,-9034768 },
+ { -27757857,247744,-15194774,-9002551,23288161,-10011936,-23869595,6503646,20650474,1804084 },
+ },
+ {
+ { -27589786,15456424,8972517,8469608,15640622,4439847,3121995,-10329713,27842616,-202328 },
+ { -15306973,2839644,22530074,10026331,4602058,5048462,28248656,5031932,-11375082,12714369 },
+ { 20807691,-7270825,29286141,11421711,-27876523,-13868230,-21227475,1035546,-19733229,12796920 },
+ },
+ {
+ { 12076899,-14301286,-8785001,-11848922,-25012791,16400684,-17591495,-12899438,3480665,-15182815 },
+ { -32361549,5457597,28548107,7833186,7303070,-11953545,-24363064,-15921875,-33374054,2771025 },
+ { -21389266,421932,26597266,6860826,22486084,-6737172,-17137485,-4210226,-24552282,15673397 },
+ },
+ {
+ { -20184622,2338216,19788685,-9620956,-4001265,-8740893,-20271184,4733254,3727144,-12934448 },
+ { 6120119,814863,-11794402,-622716,6812205,-15747771,2019594,7975683,31123697,-10958981 },
+ { 30069250,-11435332,30434654,2958439,18399564,-976289,12296869,9204260,-16432438,9648165 },
+ },
+ {
+ { 32705432,-1550977,30705658,7451065,-11805606,9631813,3305266,5248604,-26008332,-11377501 },
+ { 17219865,2375039,-31570947,-5575615,-19459679,9219903,294711,15298639,2662509,-16297073 },
+ { -1172927,-7558695,-4366770,-4287744,-21346413,-8434326,32087529,-1222777,32247248,-14389861 },
+ },
+ {
+ { 14312628,1221556,17395390,-8700143,-4945741,-8684635,-28197744,-9637817,-16027623,-13378845 },
+ { -1428825,-9678990,-9235681,6549687,-7383069,-468664,23046502,9803137,17597934,2346211 },
+ { 18510800,15337574,26171504,981392,-22241552,7827556,-23491134,-11323352,3059833,-11782870 },
+ },
+ {
+ { 10141598,6082907,17829293,-1947643,9830092,13613136,-25556636,-5544586,-33502212,3592096 },
+ { 33114168,-15889352,-26525686,-13343397,33076705,8716171,1151462,1521897,-982665,-6837803 },
+ { -32939165,-4255815,23947181,-324178,-33072974,-12305637,-16637686,3891704,26353178,693168 },
+ },
+ {
+ { 30374239,1595580,-16884039,13186931,4600344,406904,9585294,-400668,31375464,14369965 },
+ { -14370654,-7772529,1510301,6434173,-18784789,-6262728,32732230,-13108839,17901441,16011505 },
+ { 18171223,-11934626,-12500402,15197122,-11038147,-15230035,-19172240,-16046376,8764035,12309598 },
+ },
+},
+{
+ {
+ { 5975908,-5243188,-19459362,-9681747,-11541277,14015782,-23665757,1228319,17544096,-10593782 },
+ { 5811932,-1715293,3442887,-2269310,-18367348,-8359541,-18044043,-15410127,-5565381,12348900 },
+ { -31399660,11407555,25755363,6891399,-3256938,14872274,-24849353,8141295,-10632534,-585479 },
+ },
+ {
+ { -12675304,694026,-5076145,13300344,14015258,-14451394,-9698672,-11329050,30944593,1130208 },
+ { 8247766,-6710942,-26562381,-7709309,-14401939,-14648910,4652152,2488540,23550156,-271232 },
+ { 17294316,-3788438,7026748,15626851,22990044,113481,2267737,-5908146,-408818,-137719 },
+ },
+ {
+ { 16091085,-16253926,18599252,7340678,2137637,-1221657,-3364161,14550936,3260525,-7166271 },
+ { -4910104,-13332887,18550887,10864893,-16459325,-7291596,-23028869,-13204905,-12748722,2701326 },
+ { -8574695,16099415,4629974,-16340524,-20786213,-6005432,-10018363,9276971,11329923,1862132 },
+ },
+ {
+ { 14763076,-15903608,-30918270,3689867,3511892,10313526,-21951088,12219231,-9037963,-940300 },
+ { 8894987,-3446094,6150753,3013931,301220,15693451,-31981216,-2909717,-15438168,11595570 },
+ { 15214962,3537601,-26238722,-14058872,4418657,-15230761,13947276,10730794,-13489462,-4363670 },
+ },
+ {
+ { -2538306,7682793,32759013,263109,-29984731,-7955452,-22332124,-10188635,977108,699994 },
+ { -12466472,4195084,-9211532,550904,-15565337,12917920,19118110,-439841,-30534533,-14337913 },
+ { 31788461,-14507657,4799989,7372237,8808585,-14747943,9408237,-10051775,12493932,-5409317 },
+ },
+ {
+ { -25680606,5260744,-19235809,-6284470,-3695942,16566087,27218280,2607121,29375955,6024730 },
+ { 842132,-2794693,-4763381,-8722815,26332018,-12405641,11831880,6985184,-9940361,2854096 },
+ { -4847262,-7969331,2516242,-5847713,9695691,-7221186,16512645,960770,12121869,16648078 },
+ },
+ {
+ { -15218652,14667096,-13336229,2013717,30598287,-464137,-31504922,-7882064,20237806,2838411 },
+ { -19288047,4453152,15298546,-16178388,22115043,-15972604,12544294,-13470457,1068881,-12499905 },
+ { -9558883,-16518835,33238498,13506958,30505848,-1114596,-8486907,-2630053,12521378,4845654 },
+ },
+ {
+ { -28198521,10744108,-2958380,10199664,7759311,-13088600,3409348,-873400,-6482306,-12885870 },
+ { -23561822,6230156,-20382013,10655314,-24040585,-11621172,10477734,-1240216,-3113227,13974498 },
+ { 12966261,15550616,-32038948,-1615346,21025980,-629444,5642325,7188737,18895762,12629579 },
+ },
+},
+{
+ {
+ { 14741879,-14946887,22177208,-11721237,1279741,8058600,11758140,789443,32195181,3895677 },
+ { 10758205,15755439,-4509950,9243698,-4879422,6879879,-2204575,-3566119,-8982069,4429647 },
+ { -2453894,15725973,-20436342,-10410672,-5803908,-11040220,-7135870,-11642895,18047436,-15281743 },
+ },
+ {
+ { -25173001,-11307165,29759956,11776784,-22262383,-15820455,10993114,-12850837,-17620701,-9408468 },
+ { 21987233,700364,-24505048,14972008,-7774265,-5718395,32155026,2581431,-29958985,8773375 },
+ { -25568350,454463,-13211935,16126715,25240068,8594567,20656846,12017935,-7874389,-13920155 },
+ },
+ {
+ { 6028182,6263078,-31011806,-11301710,-818919,2461772,-31841174,-5468042,-1721788,-2776725 },
+ { -12278994,16624277,987579,-5922598,32908203,1248608,7719845,-4166698,28408820,6816612 },
+ { -10358094,-8237829,19549651,-12169222,22082623,16147817,20613181,13982702,-10339570,5067943 },
+ },
+ {
+ { -30505967,-3821767,12074681,13582412,-19877972,2443951,-19719286,12746132,5331210,-10105944 },
+ { 30528811,3601899,-1957090,4619785,-27361822,-15436388,24180793,-12570394,27679908,-1648928 },
+ { 9402404,-13957065,32834043,10838634,-26580150,-13237195,26653274,-8685565,22611444,-12715406 },
+ },
+ {
+ { 22190590,1118029,22736441,15130463,-30460692,-5991321,19189625,-4648942,4854859,6622139 },
+ { -8310738,-2953450,-8262579,-3388049,-10401731,-271929,13424426,-3567227,26404409,13001963 },
+ { -31241838,-15415700,-2994250,8939346,11562230,-12840670,-26064365,-11621720,-15405155,11020693 },
+ },
+ {
+ { 1866042,-7949489,-7898649,-10301010,12483315,13477547,3175636,-12424163,28761762,1406734 },
+ { -448555,-1777666,13018551,3194501,-9580420,-11161737,24760585,-4347088,25577411,-13378680 },
+ { -24290378,4759345,-690653,-1852816,2066747,10693769,-29595790,9884936,-9368926,4745410 },
+ },
+ {
+ { -9141284,6049714,-19531061,-4341411,-31260798,9944276,-15462008,-11311852,10931924,-11931931 },
+ { -16561513,14112680,-8012645,4817318,-8040464,-11414606,-22853429,10856641,-20470770,13434654 },
+ { 22759489,-10073434,-16766264,-1871422,13637442,-10168091,1765144,-12654326,28445307,-5364710 },
+ },
+ {
+ { 29875063,12493613,2795536,-3786330,1710620,15181182,-10195717,-8788675,9074234,1167180 },
+ { -26205683,11014233,-9842651,-2635485,-26908120,7532294,-18716888,-9535498,3843903,9367684 },
+ { -10969595,-6403711,9591134,9582310,11349256,108879,16235123,8601684,-139197,4242895 },
+ },
+},
+{
+ {
+ { 22092954,-13191123,-2042793,-11968512,32186753,-11517388,-6574341,2470660,-27417366,16625501 },
+ { -11057722,3042016,13770083,-9257922,584236,-544855,-7770857,2602725,-27351616,14247413 },
+ { 6314175,-10264892,-32772502,15957557,-10157730,168750,-8618807,14290061,27108877,-1180880 },
+ },
+ {
+ { -8586597,-7170966,13241782,10960156,-32991015,-13794596,33547976,-11058889,-27148451,981874 },
+ { 22833440,9293594,-32649448,-13618667,-9136966,14756819,-22928859,-13970780,-10479804,-16197962 },
+ { -7768587,3326786,-28111797,10783824,19178761,14905060,22680049,13906969,-15933690,3797899 },
+ },
+ {
+ { 21721356,-4212746,-12206123,9310182,-3882239,-13653110,23740224,-2709232,20491983,-8042152 },
+ { 9209270,-15135055,-13256557,-6167798,-731016,15289673,25947805,15286587,30997318,-6703063 },
+ { 7392032,16618386,23946583,-8039892,-13265164,-1533858,-14197445,-2321576,17649998,-250080 },
+ },
+ {
+ { -9301088,-14193827,30609526,-3049543,-25175069,-1283752,-15241566,-9525724,-2233253,7662146 },
+ { -17558673,1763594,-33114336,15908610,-30040870,-12174295,7335080,-8472199,-3174674,3440183 },
+ { -19889700,-5977008,-24111293,-9688870,10799743,-16571957,40450,-4431835,4862400,1133 },
+ },
+ {
+ { -32856209,-7873957,-5422389,14860950,-16319031,7956142,7258061,311861,-30594991,-7379421 },
+ { -3773428,-1565936,28985340,7499440,24445838,9325937,29727763,16527196,18278453,15405622 },
+ { -4381906,8508652,-19898366,-3674424,-5984453,15149970,-13313598,843523,-21875062,13626197 },
+ },
+ {
+ { 2281448,-13487055,-10915418,-2609910,1879358,16164207,-10783882,3953792,13340839,15928663 },
+ { 31727126,-7179855,-18437503,-8283652,2875793,-16390330,-25269894,-7014826,-23452306,5964753 },
+ { 4100420,-5959452,-17179337,6017714,-18705837,12227141,-26684835,11344144,2538215,-7570755 },
+ },
+ {
+ { -9433605,6123113,11159803,-2156608,30016280,14966241,-20474983,1485421,-629256,-15958862 },
+ { -26804558,4260919,11851389,9658551,-32017107,16367492,-20205425,-13191288,11659922,-11115118 },
+ { 26180396,10015009,-30844224,-8581293,5418197,9480663,2231568,-10170080,33100372,-1306171 },
+ },
+ {
+ { 15121113,-5201871,-10389905,15427821,-27509937,-15992507,21670947,4486675,-5931810,-14466380 },
+ { 16166486,-9483733,-11104130,6023908,-31926798,-1364923,2340060,-16254968,-10735770,-10039824 },
+ { 28042865,-3557089,-12126526,12259706,-3717498,-6945899,6766453,-8689599,18036436,5803270 },
+ },
+},
+{
+ {
+ { -817581,6763912,11803561,1585585,10958447,-2671165,23855391,4598332,-6159431,-14117438 },
+ { -31031306,-14256194,17332029,-2383520,31312682,-5967183,696309,50292,-20095739,11763584 },
+ { -594563,-2514283,-32234153,12643980,12650761,14811489,665117,-12613632,-19773211,-10713562 },
+ },
+ {
+ { 30464590,-11262872,-4127476,-12734478,19835327,-7105613,-24396175,2075773,-17020157,992471 },
+ { 18357185,-6994433,7766382,16342475,-29324918,411174,14578841,8080033,-11574335,-10601610 },
+ { 19598397,10334610,12555054,2555664,18821899,-10339780,21873263,16014234,26224780,16452269 },
+ },
+ {
+ { -30223925,5145196,5944548,16385966,3976735,2009897,-11377804,-7618186,-20533829,3698650 },
+ { 14187449,3448569,-10636236,-10810935,-22663880,-3433596,7268410,-10890444,27394301,12015369 },
+ { 19695761,16087646,28032085,12999827,6817792,11427614,20244189,-1312777,-13259127,-3402461 },
+ },
+ {
+ { 30860103,12735208,-1888245,-4699734,-16974906,2256940,-8166013,12298312,-8550524,-10393462 },
+ { -5719826,-11245325,-1910649,15569035,26642876,-7587760,-5789354,-15118654,-4976164,12651793 },
+ { -2848395,9953421,11531313,-5282879,26895123,-12697089,-13118820,-16517902,9768698,-2533218 },
+ },
+ {
+ { -24719459,1894651,-287698,-4704085,15348719,-8156530,32767513,12765450,4940095,10678226 },
+ { 18860224,15980149,-18987240,-1562570,-26233012,-11071856,-7843882,13944024,-24372348,16582019 },
+ { -15504260,4970268,-29893044,4175593,-20993212,-2199756,-11704054,15444560,-11003761,7989037 },
+ },
+ {
+ { 31490452,5568061,-2412803,2182383,-32336847,4531686,-32078269,6200206,-19686113,-14800171 },
+ { -17308668,-15879940,-31522777,-2831,-32887382,16375549,8680158,-16371713,28550068,-6857132 },
+ { -28126887,-5688091,16837845,-1820458,-6850681,12700016,-30039981,4364038,1155602,5988841 },
+ },
+ {
+ { 21890435,-13272907,-12624011,12154349,-7831873,15300496,23148983,-4470481,24618407,8283181 },
+ { -33136107,-10512751,9975416,6841041,-31559793,16356536,3070187,-7025928,1466169,10740210 },
+ { -1509399,-15488185,-13503385,-10655916,32799044,909394,-13938903,-5779719,-32164649,-15327040 },
+ },
+ {
+ { 3960823,-14267803,-28026090,-15918051,-19404858,13146868,15567327,951507,-3260321,-573935 },
+ { 24740841,5052253,-30094131,8961361,25877428,6165135,-24368180,14397372,-7380369,-6144105 },
+ { -28888365,3510803,-28103278,-1158478,-11238128,-10631454,-15441463,-14453128,-1625486,-6494814 },
+ },
+},
+{
+ {
+ { 793299,-9230478,8836302,-6235707,-27360908,-2369593,33152843,-4885251,-9906200,-621852 },
+ { 5666233,525582,20782575,-8038419,-24538499,14657740,16099374,1468826,-6171428,-15186581 },
+ { -4859255,-3779343,-2917758,-6748019,7778750,11688288,-30404353,-9871238,-1558923,-9863646 },
+ },
+ {
+ { 10896332,-7719704,824275,472601,-19460308,3009587,25248958,14783338,-30581476,-15757844 },
+ { 10566929,12612572,-31944212,11118703,-12633376,12362879,21752402,8822496,24003793,14264025 },
+ { 27713862,-7355973,-11008240,9227530,27050101,2504721,23886875,-13117525,13958495,-5732453 },
+ },
+ {
+ { -23481610,4867226,-27247128,3900521,29838369,-8212291,-31889399,-10041781,7340521,-15410068 },
+ { 4646514,-8011124,-22766023,-11532654,23184553,8566613,31366726,-1381061,-15066784,-10375192 },
+ { -17270517,12723032,-16993061,14878794,21619651,-6197576,27584817,3093888,-8843694,3849921 },
+ },
+ {
+ { -9064912,2103172,25561640,-15125738,-5239824,9582958,32477045,-9017955,5002294,-15550259 },
+ { -12057553,-11177906,21115585,-13365155,8808712,-12030708,16489530,13378448,-25845716,12741426 },
+ { -5946367,10645103,-30911586,15390284,-3286982,-7118677,24306472,15852464,28834118,-7646072 },
+ },
+ {
+ { -17335748,-9107057,-24531279,9434953,-8472084,-583362,-13090771,455841,20461858,5491305 },
+ { 13669248,-16095482,-12481974,-10203039,-14569770,-11893198,-24995986,11293807,-28588204,-9421832 },
+ { 28497928,6272777,-33022994,14470570,8906179,-1225630,18504674,-14165166,29867745,-8795943 },
+ },
+ {
+ { -16207023,13517196,-27799630,-13697798,24009064,-6373891,-6367600,-13175392,22853429,-4012011 },
+ { 24191378,16712145,-13931797,15217831,14542237,1646131,18603514,-11037887,12876623,-2112447 },
+ { 17902668,4518229,-411702,-2829247,26878217,5258055,-12860753,608397,16031844,3723494 },
+ },
+ {
+ { -28632773,12763728,-20446446,7577504,33001348,-13017745,17558842,-7872890,23896954,-4314245 },
+ { -20005381,-12011952,31520464,605201,2543521,5991821,-2945064,7229064,-9919646,-8826859 },
+ { 28816045,298879,-28165016,-15920938,19000928,-1665890,-12680833,-2949325,-18051778,-2082915 },
+ },
+ {
+ { 16000882,-344896,3493092,-11447198,-29504595,-13159789,12577740,16041268,-19715240,7847707 },
+ { 10151868,10572098,27312476,7922682,14825339,4723128,-32855931,-6519018,-10020567,3852848 },
+ { -11430470,15697596,-21121557,-4420647,5386314,15063598,16514493,-15932110,29330899,-15076224 },
+ },
+},
+{
+ {
+ { -25499735,-4378794,-15222908,-6901211,16615731,2051784,3303702,15490,-27548796,12314391 },
+ { 15683520,-6003043,18109120,-9980648,15337968,-5997823,-16717435,15921866,16103996,-3731215 },
+ { -23169824,-10781249,13588192,-1628807,-3798557,-1074929,-19273607,5402699,-29815713,-9841101 },
+ },
+ {
+ { 23190676,2384583,-32714340,3462154,-29903655,-1529132,-11266856,8911517,-25205859,2739713 },
+ { 21374101,-3554250,-33524649,9874411,15377179,11831242,-33529904,6134907,4931255,11987849 },
+ { -7732,-2978858,-16223486,7277597,105524,-322051,-31480539,13861388,-30076310,10117930 },
+ },
+ {
+ { -29501170,-10744872,-26163768,13051539,-25625564,5089643,-6325503,6704079,12890019,15728940 },
+ { -21972360,-11771379,-951059,-4418840,14704840,2695116,903376,-10428139,12885167,8311031 },
+ { -17516482,5352194,10384213,-13811658,7506451,13453191,26423267,4384730,1888765,-5435404 },
+ },
+ {
+ { -25817338,-3107312,-13494599,-3182506,30896459,-13921729,-32251644,-12707869,-19464434,-3340243 },
+ { -23607977,-2665774,-526091,4651136,5765089,4618330,6092245,14845197,17151279,-9854116 },
+ { -24830458,-12733720,-15165978,10367250,-29530908,-265356,22825805,-7087279,-16866484,16176525 },
+ },
+ {
+ { -23583256,6564961,20063689,3798228,-4740178,7359225,2006182,-10363426,-28746253,-10197509 },
+ { -10626600,-4486402,-13320562,-5125317,3432136,-6393229,23632037,-1940610,32808310,1099883 },
+ { 15030977,5768825,-27451236,-2887299,-6427378,-15361371,-15277896,-6809350,2051441,-15225865 },
+ },
+ {
+ { -3362323,-7239372,7517890,9824992,23555850,295369,5148398,-14154188,-22686354,16633660 },
+ { 4577086,-16752288,13249841,-15304328,19958763,-14537274,18559670,-10759549,8402478,-9864273 },
+ { -28406330,-1051581,-26790155,-907698,-17212414,-11030789,9453451,-14980072,17983010,9967138 },
+ },
+ {
+ { -25762494,6524722,26585488,9969270,24709298,1220360,-1677990,7806337,17507396,3651560 },
+ { -10420457,-4118111,14584639,15971087,-15768321,8861010,26556809,-5574557,-18553322,-11357135 },
+ { 2839101,14284142,4029895,3472686,14402957,12689363,-26642121,8459447,-5605463,-7621941 },
+ },
+ {
+ { -4839289,-3535444,9744961,2871048,25113978,3187018,-25110813,-849066,17258084,-7977739 },
+ { 18164541,-10595176,-17154882,-1542417,19237078,-9745295,23357533,-15217008,26908270,12150756 },
+ { -30264870,-7647865,5112249,-7036672,-1499807,-6974257,43168,-5537701,-32302074,16215819 },
+ },
+},
+{
+ {
+ { -6898905,9824394,-12304779,-4401089,-31397141,-6276835,32574489,12532905,-7503072,-8675347 },
+ { -27343522,-16515468,-27151524,-10722951,946346,16291093,254968,7168080,21676107,-1943028 },
+ { 21260961,-8424752,-16831886,-11920822,-23677961,3968121,-3651949,-6215466,-3556191,-7913075 },
+ },
+ {
+ { 16544754,13250366,-16804428,15546242,-4583003,12757258,-2462308,-8680336,-18907032,-9662799 },
+ { -2415239,-15577728,18312303,4964443,-15272530,-12653564,26820651,16690659,25459437,-4564609 },
+ { -25144690,11425020,28423002,-11020557,-6144921,-15826224,9142795,-2391602,-6432418,-1644817 },
+ },
+ {
+ { -23104652,6253476,16964147,-3768872,-25113972,-12296437,-27457225,-16344658,6335692,7249989 },
+ { -30333227,13979675,7503222,-12368314,-11956721,-4621693,-30272269,2682242,25993170,-12478523 },
+ { 4364628,5930691,32304656,-10044554,-8054781,15091131,22857016,-10598955,31820368,15075278 },
+ },
+ {
+ { 31879134,-8918693,17258761,90626,-8041836,-4917709,24162788,-9650886,-17970238,12833045 },
+ { 19073683,14851414,-24403169,-11860168,7625278,11091125,-19619190,2074449,-9413939,14905377 },
+ { 24483667,-11935567,-2518866,-11547418,-1553130,15355506,-25282080,9253129,27628530,-7555480 },
+ },
+ {
+ { 17597607,8340603,19355617,552187,26198470,-3176583,4593324,-9157582,-14110875,15297016 },
+ { 510886,14337390,-31785257,16638632,6328095,2713355,-20217417,-11864220,8683221,2921426 },
+ { 18606791,11874196,27155355,-5281482,-24031742,6265446,-25178240,-1278924,4674690,13890525 },
+ },
+ {
+ { 13609624,13069022,-27372361,-13055908,24360586,9592974,14977157,9835105,4389687,288396 },
+ { 9922506,-519394,13613107,5883594,-18758345,-434263,-12304062,8317628,23388070,16052080 },
+ { 12720016,11937594,-31970060,-5028689,26900120,8561328,-20155687,-11632979,-14754271,-10812892 },
+ },
+ {
+ { 15961858,14150409,26716931,-665832,-22794328,13603569,11829573,7467844,-28822128,929275 },
+ { 11038231,-11582396,-27310482,-7316562,-10498527,-16307831,-23479533,-9371869,-21393143,2465074 },
+ { 20017163,-4323226,27915242,1529148,12396362,15675764,13817261,-9658066,2463391,-4622140 },
+ },
+ {
+ { -16358878,-12663911,-12065183,4996454,-1256422,1073572,9583558,12851107,4003896,12673717 },
+ { -1731589,-15155870,-3262930,16143082,19294135,13385325,14741514,-9103726,7903886,2348101 },
+ { 24536016,-16515207,12715592,-3862155,1511293,10047386,-3842346,-7129159,-28377538,10048127 },
+ },
+},
+{
+ {
+ { -12622226,-6204820,30718825,2591312,-10617028,12192840,18873298,-7297090,-32297756,15221632 },
+ { -26478122,-11103864,11546244,-1852483,9180880,7656409,-21343950,2095755,29769758,6593415 },
+ { -31994208,-2907461,4176912,3264766,12538965,-868111,26312345,-6118678,30958054,8292160 },
+ },
+ {
+ { 31429822,-13959116,29173532,15632448,12174511,-2760094,32808831,3977186,26143136,-3148876 },
+ { 22648901,1402143,-22799984,13746059,7936347,365344,-8668633,-1674433,-3758243,-2304625 },
+ { -15491917,8012313,-2514730,-12702462,-23965846,-10254029,-1612713,-1535569,-16664475,8194478 },
+ },
+ {
+ { 27338066,-7507420,-7414224,10140405,-19026427,-6589889,27277191,8855376,28572286,3005164 },
+ { 26287124,4821776,25476601,-4145903,-3764513,-15788984,-18008582,1182479,-26094821,-13079595 },
+ { -7171154,3178080,23970071,6201893,-17195577,-4489192,-21876275,-13982627,32208683,-1198248 },
+ },
+ {
+ { -16657702,2817643,-10286362,14811298,6024667,13349505,-27315504,-10497842,-27672585,-11539858 },
+ { 15941029,-9405932,-21367050,8062055,31876073,-238629,-15278393,-1444429,15397331,-4130193 },
+ { 8934485,-13485467,-23286397,-13423241,-32446090,14047986,31170398,-1441021,-27505566,15087184 },
+ },
+ {
+ { -18357243,-2156491,24524913,-16677868,15520427,-6360776,-15502406,11461896,16788528,-5868942 },
+ { -1947386,16013773,21750665,3714552,-17401782,-16055433,-3770287,-10323320,31322514,-11615635 },
+ { 21426655,-5650218,-13648287,-5347537,-28812189,-4920970,-18275391,-14621414,13040862,-12112948 },
+ },
+ {
+ { 11293895,12478086,-27136401,15083750,-29307421,14748872,14555558,-13417103,1613711,4896935 },
+ { -25894883,15323294,-8489791,-8057900,25967126,-13425460,2825960,-4897045,-23971776,-11267415 },
+ { -15924766,-5229880,-17443532,6410664,3622847,10243618,20615400,12405433,-23753030,-8436416 },
+ },
+ {
+ { -7091295,12556208,-20191352,9025187,-17072479,4333801,4378436,2432030,23097949,-566018 },
+ { 4565804,-16025654,20084412,-7842817,1724999,189254,24767264,10103221,-18512313,2424778 },
+ { 366633,-11976806,8173090,-6890119,30788634,5745705,-7168678,1344109,-3642553,12412659 },
+ },
+ {
+ { -24001791,7690286,14929416,-168257,-32210835,-13412986,24162697,-15326504,-3141501,11179385 },
+ { 18289522,-14724954,8056945,16430056,-21729724,7842514,-6001441,-1486897,-18684645,-11443503 },
+ { 476239,6601091,-6152790,-9723375,17503545,-4863900,27672959,13403813,11052904,5219329 },
+ },
+},
+{
+ {
+ { 20678546,-8375738,-32671898,8849123,-5009758,14574752,31186971,-3973730,9014762,-8579056 },
+ { -13644050,-10350239,-15962508,5075808,-1514661,-11534600,-33102500,9160280,8473550,-3256838 },
+ { 24900749,14435722,17209120,-15292541,-22592275,9878983,-7689309,-16335821,-24568481,11788948 },
+ },
+ {
+ { -3118155,-11395194,-13802089,14797441,9652448,-6845904,-20037437,10410733,-24568470,-1458691 },
+ { -15659161,16736706,-22467150,10215878,-9097177,7563911,11871841,-12505194,-18513325,8464118 },
+ { -23400612,8348507,-14585951,-861714,-3950205,-6373419,14325289,8628612,33313881,-8370517 },
+ },
+ {
+ { -20186973,-4967935,22367356,5271547,-1097117,-4788838,-24805667,-10236854,-8940735,-5818269 },
+ { -6948785,-1795212,-32625683,-16021179,32635414,-7374245,15989197,-12838188,28358192,-4253904 },
+ { -23561781,-2799059,-32351682,-1661963,-9147719,10429267,-16637684,4072016,-5351664,5596589 },
+ },
+ {
+ { -28236598,-3390048,12312896,6213178,3117142,16078565,29266239,2557221,1768301,15373193 },
+ { -7243358,-3246960,-4593467,-7553353,-127927,-912245,-1090902,-4504991,-24660491,3442910 },
+ { -30210571,5124043,14181784,8197961,18964734,-11939093,22597931,7176455,-18585478,13365930 },
+ },
+ {
+ { -7877390,-1499958,8324673,4690079,6261860,890446,24538107,-8570186,-9689599,-3031667 },
+ { 25008904,-10771599,-4305031,-9638010,16265036,15721635,683793,-11823784,15723479,-15163481 },
+ { -9660625,12374379,-27006999,-7026148,-7724114,-12314514,11879682,5400171,519526,-1235876 },
+ },
+ {
+ { 22258397,-16332233,-7869817,14613016,-22520255,-2950923,-20353881,7315967,16648397,7605640 },
+ { -8081308,-8464597,-8223311,9719710,19259459,-15348212,23994942,-5281555,-9468848,4763278 },
+ { -21699244,9220969,-15730624,1084137,-25476107,-2852390,31088447,-7764523,-11356529,728112 },
+ },
+ {
+ { 26047220,-11751471,-6900323,-16521798,24092068,9158119,-4273545,-12555558,-29365436,-5498272 },
+ { 17510331,-322857,5854289,8403524,17133918,-3112612,-28111007,12327945,10750447,10014012 },
+ { -10312768,3936952,9156313,-8897683,16498692,-994647,-27481051,-666732,3424691,7540221 },
+ },
+ {
+ { 30322361,-6964110,11361005,-4143317,7433304,4989748,-7071422,-16317219,-9244265,15258046 },
+ { 13054562,-2779497,19155474,469045,-12482797,4566042,5631406,2711395,1062915,-5136345 },
+ { -19240248,-11254599,-29509029,-7499965,-5835763,13005411,-6066489,12194497,32960380,1459310 },
+ },
+},
+{
+ {
+ { 19852034,7027924,23669353,10020366,8586503,-6657907,394197,-6101885,18638003,-11174937 },
+ { 31395534,15098109,26581030,8030562,-16527914,-5007134,9012486,-7584354,-6643087,-5442636 },
+ { -9192165,-2347377,-1997099,4529534,25766844,607986,-13222,9677543,-32294889,-6456008 },
+ },
+ {
+ { -2444496,-149937,29348902,8186665,1873760,12489863,-30934579,-7839692,-7852844,-8138429 },
+ { -15236356,-15433509,7766470,746860,26346930,-10221762,-27333451,10754588,-9431476,5203576 },
+ { 31834314,14135496,-770007,5159118,20917671,-16768096,-7467973,-7337524,31809243,7347066 },
+ },
+ {
+ { -9606723,-11874240,20414459,13033986,13716524,-11691881,19797970,-12211255,15192876,-2087490 },
+ { -12663563,-2181719,1168162,-3804809,26747877,-14138091,10609330,12694420,33473243,-13382104 },
+ { 33184999,11180355,15832085,-11385430,-1633671,225884,15089336,-11023903,-6135662,14480053 },
+ },
+ {
+ { 31308717,-5619998,31030840,-1897099,15674547,-6582883,5496208,13685227,27595050,8737275 },
+ { -20318852,-15150239,10933843,-16178022,8335352,-7546022,-31008351,-12610604,26498114,66511 },
+ { 22644454,-8761729,-16671776,4884562,-3105614,-13559366,30540766,-4286747,-13327787,-7515095 },
+ },
+ {
+ { -28017847,9834845,18617207,-2681312,-3401956,-13307506,8205540,13585437,-17127465,15115439 },
+ { 23711543,-672915,31206561,-8362711,6164647,-9709987,-33535882,-1426096,8236921,16492939 },
+ { -23910559,-13515526,-26299483,-4503841,25005590,-7687270,19574902,10071562,6708380,-6222424 },
+ },
+ {
+ { 2101391,-4930054,19702731,2367575,-15427167,1047675,5301017,9328700,29955601,-11678310 },
+ { 3096359,9271816,-21620864,-15521844,-14847996,-7592937,-25892142,-12635595,-9917575,6216608 },
+ { -32615849,338663,-25195611,2510422,-29213566,-13820213,24822830,-6146567,-26767480,7525079 },
+ },
+ {
+ { -23066649,-13985623,16133487,-7896178,-3389565,778788,-910336,-2782495,-19386633,11994101 },
+ { 21691500,-13624626,-641331,-14367021,3285881,-3483596,-25064666,9718258,-7477437,13381418 },
+ { 18445390,-4202236,14979846,11622458,-1727110,-3582980,23111648,-6375247,28535282,15779576 },
+ },
+ {
+ { 30098053,3089662,-9234387,16662135,-21306940,11308411,-14068454,12021730,9955285,-16303356 },
+ { 9734894,-14576830,-7473633,-9138735,2060392,11313496,-18426029,9924399,20194861,13380996 },
+ { -26378102,-7965207,-22167821,15789297,-18055342,-6168792,-1984914,15707771,26342023,10146099 },
+ },
+},
+{
+ {
+ { -26016874,-219943,21339191,-41388,19745256,-2878700,-29637280,2227040,21612326,-545728 },
+ { -13077387,1184228,23562814,-5970442,-20351244,-6348714,25764461,12243797,-20856566,11649658 },
+ { -10031494,11262626,27384172,2271902,26947504,-15997771,39944,6114064,33514190,2333242 },
+ },
+ {
+ { -21433588,-12421821,8119782,7219913,-21830522,-9016134,-6679750,-12670638,24350578,-13450001 },
+ { -4116307,-11271533,-23886186,4843615,-30088339,690623,-31536088,-10406836,8317860,12352766 },
+ { 18200138,-14475911,-33087759,-2696619,-23702521,-9102511,-23552096,-2287550,20712163,6719373 },
+ },
+ {
+ { 26656208,6075253,-7858556,1886072,-28344043,4262326,11117530,-3763210,26224235,-3297458 },
+ { -17168938,-14854097,-3395676,-16369877,-19954045,14050420,21728352,9493610,18620611,-16428628 },
+ { -13323321,13325349,11432106,5964811,18609221,6062965,-5269471,-9725556,-30701573,-16479657 },
+ },
+ {
+ { -23860538,-11233159,26961357,1640861,-32413112,-16737940,12248509,-5240639,13735342,1934062 },
+ { 25089769,6742589,17081145,-13406266,21909293,-16067981,-15136294,-3765346,-21277997,5473616 },
+ { 31883677,-7961101,1083432,-11572403,22828471,13290673,-7125085,12469656,29111212,-5451014 },
+ },
+ {
+ { 24244947,-15050407,-26262976,2791540,-14997599,16666678,24367466,6388839,-10295587,452383 },
+ { -25640782,-3417841,5217916,16224624,19987036,-4082269,-24236251,-5915248,15766062,8407814 },
+ { -20406999,13990231,15495425,16395525,5377168,15166495,-8917023,-4388953,-8067909,2276718 },
+ },
+ {
+ { 30157918,12924066,-17712050,9245753,19895028,3368142,-23827587,5096219,22740376,-7303417 },
+ { 2041139,-14256350,7783687,13876377,-25946985,-13352459,24051124,13742383,-15637599,13295222 },
+ { 33338237,-8505733,12532113,7977527,9106186,-1715251,-17720195,-4612972,-4451357,-14669444 },
+ },
+ {
+ { -20045281,5454097,-14346548,6447146,28862071,1883651,-2469266,-4141880,7770569,9620597 },
+ { 23208068,7979712,33071466,8149229,1758231,-10834995,30945528,-1694323,-33502340,-14767970 },
+ { 1439958,-16270480,-1079989,-793782,4625402,10647766,-5043801,1220118,30494170,-11440799 },
+ },
+ {
+ { -5037580,-13028295,-2970559,-3061767,15640974,-6701666,-26739026,926050,-1684339,-13333647 },
+ { 13908495,-3549272,30919928,-6273825,-21521863,7989039,9021034,9078865,3353509,4033511 },
+ { -29663431,-15113610,32259991,-344482,24295849,-12912123,23161163,8839127,27485041,7356032 },
+ },
+},
+{
+ {
+ { 9661027,705443,11980065,-5370154,-1628543,14661173,-6346142,2625015,28431036,-16771834 },
+ { -23839233,-8311415,-25945511,7480958,-17681669,-8354183,-22545972,14150565,15970762,4099461 },
+ { 29262576,16756590,26350592,-8793563,8529671,-11208050,13617293,-9937143,11465739,8317062 },
+ },
+ {
+ { -25493081,-6962928,32500200,-9419051,-23038724,-2302222,14898637,3848455,20969334,-5157516 },
+ { -20384450,-14347713,-18336405,13884722,-33039454,2842114,-21610826,-3649888,11177095,14989547 },
+ { -24496721,-11716016,16959896,2278463,12066309,10137771,13515641,2581286,-28487508,9930240 },
+ },
+ {
+ { -17751622,-2097826,16544300,-13009300,-15914807,-14949081,18345767,-13403753,16291481,-5314038 },
+ { -33229194,2553288,32678213,9875984,8534129,6889387,-9676774,6957617,4368891,9788741 },
+ { 16660756,7281060,-10830758,12911820,20108584,-8101676,-21722536,-8613148,16250552,-11111103 },
+ },
+ {
+ { -19765507,2390526,-16551031,14161980,1905286,6414907,4689584,10604807,-30190403,4782747 },
+ { -1354539,14736941,-7367442,-13292886,7710542,-14155590,-9981571,4383045,22546403,437323 },
+ { 31665577,-12180464,-16186830,1491339,-18368625,3294682,27343084,2786261,-30633590,-14097016 },
+ },
+ {
+ { -14467279,-683715,-33374107,7448552,19294360,14334329,-19690631,2355319,-19284671,-6114373 },
+ { 15121312,-15796162,6377020,-6031361,-10798111,-12957845,18952177,15496498,-29380133,11754228 },
+ { -2637277,-13483075,8488727,-14303896,12728761,-1622493,7141596,11724556,22761615,-10134141 },
+ },
+ {
+ { 16918416,11729663,-18083579,3022987,-31015732,-13339659,-28741185,-12227393,32851222,11717399 },
+ { 11166634,7338049,-6722523,4531520,-29468672,-7302055,31474879,3483633,-1193175,-4030831 },
+ { -185635,9921305,31456609,-13536438,-12013818,13348923,33142652,6546660,-19985279,-3948376 },
+ },
+ {
+ { -32460596,11266712,-11197107,-7899103,31703694,3855903,-8537131,-12833048,-30772034,-15486313 },
+ { -18006477,12709068,3991746,-6479188,-21491523,-10550425,-31135347,-16049879,10928917,3011958 },
+ { -6957757,-15594337,31696059,334240,29576716,14796075,-30831056,-12805180,18008031,10258577 },
+ },
+ {
+ { -22448644,15655569,7018479,-4410003,-30314266,-1201591,-1853465,1367120,25127874,6671743 },
+ { 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684 },
+ { -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476 },
+ },
+},
diff --git a/src/ext/ed25519/ref10/base.py b/src/ext/ed25519/ref10/base.py
new file mode 100644
index 0000000000..84accc8580
--- /dev/null
+++ b/src/ext/ed25519/ref10/base.py
@@ -0,0 +1,65 @@
+b = 256
+q = 2**255 - 19
+l = 2**252 + 27742317777372353535851937790883648493
+
+def expmod(b,e,m):
+ if e == 0: return 1
+ t = expmod(b,e/2,m)**2 % m
+ if e & 1: t = (t*b) % m
+ return t
+
+def inv(x):
+ return expmod(x,q-2,q)
+
+d = -121665 * inv(121666)
+I = expmod(2,(q-1)/4,q)
+
+def xrecover(y):
+ xx = (y*y-1) * inv(d*y*y+1)
+ x = expmod(xx,(q+3)/8,q)
+ if (x*x - xx) % q != 0: x = (x*I) % q
+ if x % 2 != 0: x = q-x
+ return x
+
+By = 4 * inv(5)
+Bx = xrecover(By)
+B = [Bx % q,By % q]
+
+def edwards(P,Q):
+ x1 = P[0]
+ y1 = P[1]
+ x2 = Q[0]
+ y2 = Q[1]
+ x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2)
+ y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2)
+ return [x3 % q,y3 % q]
+
+def radix255(x):
+ x = x % q
+ if x + x > q: x -= q
+ x = [x,0,0,0,0,0,0,0,0,0]
+ bits = [26,25,26,25,26,25,26,25,26,25]
+ for i in range(9):
+ carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
+ x[i] -= carry * 2**bits[i]
+ x[i + 1] += carry
+ result = ""
+ for i in range(9):
+ result = result+str(x[i])+","
+ result = result+str(x[9])
+ return result
+
+Bi = B
+for i in range(32):
+ print "{"
+ Bij = Bi
+ for j in range(8):
+ print " {"
+ print " {",radix255(Bij[1]+Bij[0]),"},"
+ print " {",radix255(Bij[1]-Bij[0]),"},"
+ print " {",radix255(2*d*Bij[0]*Bij[1]),"},"
+ Bij = edwards(Bij,Bi)
+ print " },"
+ print "},"
+ for k in range(8):
+ Bi = edwards(Bi,Bi)
diff --git a/src/ext/ed25519/ref10/base2.h b/src/ext/ed25519/ref10/base2.h
new file mode 100644
index 0000000000..8c538440ff
--- /dev/null
+++ b/src/ext/ed25519/ref10/base2.h
@@ -0,0 +1,40 @@
+ {
+ { 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 },
+ { -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 },
+ { -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 },
+ },
+ {
+ { 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 },
+ { 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 },
+ { 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 },
+ },
+ {
+ { 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 },
+ { 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 },
+ { 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 },
+ },
+ {
+ { 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 },
+ { -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 },
+ { 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 },
+ },
+ {
+ { -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 },
+ { -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 },
+ { 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 },
+ },
+ {
+ { -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 },
+ { 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 },
+ { 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 },
+ },
+ {
+ { -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 },
+ { -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 },
+ { -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 },
+ },
+ {
+ { -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 },
+ { -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 },
+ { -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 },
+ },
diff --git a/src/ext/ed25519/ref10/base2.py b/src/ext/ed25519/ref10/base2.py
new file mode 100644
index 0000000000..5e4e8739d0
--- /dev/null
+++ b/src/ext/ed25519/ref10/base2.py
@@ -0,0 +1,60 @@
+b = 256
+q = 2**255 - 19
+l = 2**252 + 27742317777372353535851937790883648493
+
+def expmod(b,e,m):
+ if e == 0: return 1
+ t = expmod(b,e/2,m)**2 % m
+ if e & 1: t = (t*b) % m
+ return t
+
+def inv(x):
+ return expmod(x,q-2,q)
+
+d = -121665 * inv(121666)
+I = expmod(2,(q-1)/4,q)
+
+def xrecover(y):
+ xx = (y*y-1) * inv(d*y*y+1)
+ x = expmod(xx,(q+3)/8,q)
+ if (x*x - xx) % q != 0: x = (x*I) % q
+ if x % 2 != 0: x = q-x
+ return x
+
+By = 4 * inv(5)
+Bx = xrecover(By)
+B = [Bx % q,By % q]
+
+def edwards(P,Q):
+ x1 = P[0]
+ y1 = P[1]
+ x2 = Q[0]
+ y2 = Q[1]
+ x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2)
+ y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2)
+ return [x3 % q,y3 % q]
+
+def radix255(x):
+ x = x % q
+ if x + x > q: x -= q
+ x = [x,0,0,0,0,0,0,0,0,0]
+ bits = [26,25,26,25,26,25,26,25,26,25]
+ for i in range(9):
+ carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
+ x[i] -= carry * 2**bits[i]
+ x[i + 1] += carry
+ result = ""
+ for i in range(9):
+ result = result+str(x[i])+","
+ result = result+str(x[9])
+ return result
+
+Bi = B
+
+for i in range(8):
+ print " {"
+ print " {",radix255(Bi[1]+Bi[0]),"},"
+ print " {",radix255(Bi[1]-Bi[0]),"},"
+ print " {",radix255(2*d*Bi[0]*Bi[1]),"},"
+ print " },"
+ Bi = edwards(B,edwards(B,Bi))
diff --git a/src/ext/ed25519/ref10/blinding.c b/src/ext/ed25519/ref10/blinding.c
new file mode 100644
index 0000000000..4d9a9cbbe7
--- /dev/null
+++ b/src/ext/ed25519/ref10/blinding.c
@@ -0,0 +1,76 @@
+/* Added to ref10 for Tor. We place this in the public domain. Alternatively,
+ * you may have it under the Creative Commons 0 "CC0" license. */
+//#include "fe.h"
+#include "ge.h"
+#include "sc.h"
+#include "crypto_hash_sha512.h"
+#include "ed25519_ref10.h"
+
+#include <string.h>
+#include "crypto.h"
+
+static void
+gettweak(unsigned char *out, const unsigned char *param)
+{
+ const char str[] = "Derive temporary signing key";
+ crypto_hash_sha512_2(out, (const unsigned char*)str, strlen(str), param, 32);
+ out[0] &= 248; /* Is this necessary necessary ? */
+ out[31] &= 63;
+ out[31] |= 64;
+}
+
+int ed25519_ref10_blind_secret_key(unsigned char *out,
+ const unsigned char *inp,
+ const unsigned char *param)
+{
+ const char str[] = "Derive temporary signing key hash input";
+ unsigned char tweak[64];
+ unsigned char zero[32];
+ gettweak(tweak, param);
+
+ memset(zero, 0, 32);
+ sc_muladd(out, inp, tweak, zero);
+
+ crypto_hash_sha512_2(tweak, (const unsigned char *)str, strlen(str),
+ inp+32, 32);
+ memcpy(out+32, tweak, 32);
+
+ memwipe(tweak, 0, sizeof(tweak));
+
+ return 0;
+}
+
+int ed25519_ref10_blind_public_key(unsigned char *out,
+ const unsigned char *inp,
+ const unsigned char *param)
+{
+ unsigned char tweak[64];
+ unsigned char zero[32];
+ unsigned char pkcopy[32];
+ ge_p3 A;
+ ge_p2 Aprime;
+
+ gettweak(tweak, param);
+
+ memset(zero, 0, sizeof(zero));
+ /* Not the greatest implementation of all of this. I wish I had
+ * better-suited primitives to work with here... (but I don't wish that so
+ * strongly that I'm about to code my own ge_scalarmult_vartime). */
+
+ /* We negate the public key first, so that we can pass it to
+ * frombytes_negate_vartime, which negates it again. If there were a
+ * "ge_frombytes", we'd use that, but there isn't. */
+ memcpy(pkcopy, inp, 32);
+ pkcopy[31] ^= (1<<7);
+ ge_frombytes_negate_vartime(&A, pkcopy);
+ /* There isn't a regular ge_scalarmult -- we have to do tweak*A + zero*B. */
+ ge_double_scalarmult_vartime(&Aprime, tweak, &A, zero);
+ ge_tobytes(out, &Aprime);
+
+ memwipe(tweak, 0, sizeof(tweak));
+ memwipe(&A, 0, sizeof(A));
+ memwipe(&Aprime, 0, sizeof(Aprime));
+ memwipe(pkcopy, 0, sizeof(pkcopy));
+
+ return 0;
+}
diff --git a/src/ext/ed25519/ref10/crypto_hash_sha512.h b/src/ext/ed25519/ref10/crypto_hash_sha512.h
new file mode 100644
index 0000000000..0278571522
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_hash_sha512.h
@@ -0,0 +1,30 @@
+/* Added for Tor. */
+#include <openssl/sha.h>
+
+/* Set 'out' to the 512-bit SHA512 hash of the 'len'-byte string in 'inp' */
+#define crypto_hash_sha512(out, inp, len) \
+ SHA512((inp), (len), (out))
+
+/* Set 'out' to the 512-bit SHA512 hash of the 'len1'-byte string in 'inp1',
+ * concatenated with the 'len2'-byte string in 'inp2'. */
+#define crypto_hash_sha512_2(out, inp1, len1, inp2, len2) \
+ do { \
+ SHA512_CTX sha_ctx_; \
+ SHA512_Init(&sha_ctx_); \
+ SHA512_Update(&sha_ctx_, (inp1), (len1)); \
+ SHA512_Update(&sha_ctx_, (inp2), (len2)); \
+ SHA512_Final((out), &sha_ctx_); \
+ } while(0)
+
+/* Set 'out' to the 512-bit SHA512 hash of the 'len1'-byte string in 'inp1',
+ * concatenated with the 'len2'-byte string in 'inp2', concatenated with
+ * the 'len3'-byte string in 'len3'. */
+#define crypto_hash_sha512_3(out, inp1, len1, inp2, len2, inp3, len3) \
+ do { \
+ SHA512_CTX sha_ctx_; \
+ SHA512_Init(&sha_ctx_); \
+ SHA512_Update(&sha_ctx_, (inp1), (len1)); \
+ SHA512_Update(&sha_ctx_, (inp2), (len2)); \
+ SHA512_Update(&sha_ctx_, (inp3), (len3)); \
+ SHA512_Final((out), &sha_ctx_); \
+ } while(0)
diff --git a/src/ext/ed25519/ref10/crypto_int32.h b/src/ext/ed25519/ref10/crypto_int32.h
new file mode 100644
index 0000000000..dd13c91bd0
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_int32.h
@@ -0,0 +1,25 @@
+/* Added for Tor. */
+
+#ifndef CRYPTO_INT32_H
+#define CRYPTO_INT32_H
+
+#include "torint.h"
+#define crypto_int32 int32_t
+#define crypto_uint32 uint32_t
+
+/*
+ Stop signed left shifts overflowing
+ by using unsigned types for bitwise operations
+ */
+
+#ifndef OVERFLOW_SAFE_SIGNED_LSHIFT
+#define OVERFLOW_SAFE_SIGNED_LSHIFT(s, lshift, utype, stype) \
+ ((stype)((utype)(s) << (utype)(lshift)))
+#endif
+
+#define SHL32(s, lshift) \
+ OVERFLOW_SAFE_SIGNED_LSHIFT(s, lshift, crypto_uint32, crypto_int32)
+#define SHL8(s, lshift) \
+ OVERFLOW_SAFE_SIGNED_LSHIFT(s, lshift, unsigned char, signed char)
+
+#endif /* CRYPTO_INT32_H */
diff --git a/src/ext/ed25519/ref10/crypto_int64.h b/src/ext/ed25519/ref10/crypto_int64.h
new file mode 100644
index 0000000000..46e8852ed0
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_int64.h
@@ -0,0 +1,23 @@
+/* Added for Tor. */
+
+#ifndef CRYPTO_INT64_H
+#define CRYPTO_INT64_H
+
+#include "torint.h"
+#define crypto_int64 int64_t
+#define crypto_uint64 uint64_t
+
+/*
+ Stop signed left shifts overflowing
+ by using unsigned types for bitwise operations
+ */
+
+#ifndef OVERFLOW_SAFE_SIGNED_LSHIFT
+#define OVERFLOW_SAFE_SIGNED_LSHIFT(s, lshift, utype, stype) \
+ ((stype)((utype)(s) << (utype)(lshift)))
+#endif
+
+#define SHL64(s, lshift) \
+ OVERFLOW_SAFE_SIGNED_LSHIFT(s, lshift, crypto_uint64, crypto_int64)
+
+#endif /* CRYPTO_INT64_H */
diff --git a/src/ext/ed25519/ref10/crypto_sign.h b/src/ext/ed25519/ref10/crypto_sign.h
new file mode 100644
index 0000000000..549626793a
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_sign.h
@@ -0,0 +1,9 @@
+/* Added for Tor */
+#define crypto_sign ed25519_ref10_sign
+#define crypto_sign_keypair ed25519_ref10_keygen
+#define crypto_sign_seckey ed25519_ref10_seckey
+#define crypto_sign_seckey_expand ed25519_ref10_seckey_expand
+#define crypto_sign_pubkey ed25519_ref10_pubkey
+#define crypto_sign_open ed25519_ref10_open
+
+#include "ed25519_ref10.h"
diff --git a/src/ext/ed25519/ref10/crypto_uint32.h b/src/ext/ed25519/ref10/crypto_uint32.h
new file mode 100644
index 0000000000..62655a5b66
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_uint32.h
@@ -0,0 +1,3 @@
+/* Added for Tor. */
+#include "torint.h"
+#define crypto_uint32 uint32_t
diff --git a/src/ext/ed25519/ref10/crypto_uint64.h b/src/ext/ed25519/ref10/crypto_uint64.h
new file mode 100644
index 0000000000..cbda882a6a
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_uint64.h
@@ -0,0 +1,3 @@
+/* Added for Tor. */
+#include "torint.h"
+#define crypto_uint64 uint64_t
diff --git a/src/ext/ed25519/ref10/crypto_verify_32.h b/src/ext/ed25519/ref10/crypto_verify_32.h
new file mode 100644
index 0000000000..0f63efc7a3
--- /dev/null
+++ b/src/ext/ed25519/ref10/crypto_verify_32.h
@@ -0,0 +1,5 @@
+/* Added for Tor. */
+#include "di_ops.h"
+#define crypto_verify_32(a,b) \
+ (! tor_memeq((a), (b), 32))
+
diff --git a/src/ext/ed25519/ref10/d.h b/src/ext/ed25519/ref10/d.h
new file mode 100644
index 0000000000..e25f578350
--- /dev/null
+++ b/src/ext/ed25519/ref10/d.h
@@ -0,0 +1 @@
+-10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116
diff --git a/src/ext/ed25519/ref10/d.py b/src/ext/ed25519/ref10/d.py
new file mode 100644
index 0000000000..8995bb86a3
--- /dev/null
+++ b/src/ext/ed25519/ref10/d.py
@@ -0,0 +1,28 @@
+q = 2**255 - 19
+
+def expmod(b,e,m):
+ if e == 0: return 1
+ t = expmod(b,e/2,m)**2 % m
+ if e & 1: t = (t*b) % m
+ return t
+
+def inv(x):
+ return expmod(x,q-2,q)
+
+def radix255(x):
+ x = x % q
+ if x + x > q: x -= q
+ x = [x,0,0,0,0,0,0,0,0,0]
+ bits = [26,25,26,25,26,25,26,25,26,25]
+ for i in range(9):
+ carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
+ x[i] -= carry * 2**bits[i]
+ x[i + 1] += carry
+ result = ""
+ for i in range(9):
+ result = result+str(x[i])+","
+ result = result+str(x[9])
+ return result
+
+d = -121665 * inv(121666)
+print radix255(d)
diff --git a/src/ext/ed25519/ref10/d2.h b/src/ext/ed25519/ref10/d2.h
new file mode 100644
index 0000000000..01aaec7512
--- /dev/null
+++ b/src/ext/ed25519/ref10/d2.h
@@ -0,0 +1 @@
+-21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199
diff --git a/src/ext/ed25519/ref10/d2.py b/src/ext/ed25519/ref10/d2.py
new file mode 100644
index 0000000000..79841758be
--- /dev/null
+++ b/src/ext/ed25519/ref10/d2.py
@@ -0,0 +1,28 @@
+q = 2**255 - 19
+
+def expmod(b,e,m):
+ if e == 0: return 1
+ t = expmod(b,e/2,m)**2 % m
+ if e & 1: t = (t*b) % m
+ return t
+
+def inv(x):
+ return expmod(x,q-2,q)
+
+def radix255(x):
+ x = x % q
+ if x + x > q: x -= q
+ x = [x,0,0,0,0,0,0,0,0,0]
+ bits = [26,25,26,25,26,25,26,25,26,25]
+ for i in range(9):
+ carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
+ x[i] -= carry * 2**bits[i]
+ x[i + 1] += carry
+ result = ""
+ for i in range(9):
+ result = result+str(x[i])+","
+ result = result+str(x[9])
+ return result
+
+d = -121665 * inv(121666)
+print radix255(d*2)
diff --git a/src/ext/ed25519/ref10/ed25519_ref10.h b/src/ext/ed25519/ref10/ed25519_ref10.h
new file mode 100644
index 0000000000..af7e21a2ad
--- /dev/null
+++ b/src/ext/ed25519/ref10/ed25519_ref10.h
@@ -0,0 +1,30 @@
+/* Added for Tor */
+#ifndef SRC_EXT_ED25519_REF10_H_INCLUDED_
+#define SRC_EXT_ED25519_REF10_H_INCLUDED_
+#include <torint.h>
+
+int ed25519_ref10_seckey(unsigned char *sk);
+int ed25519_ref10_seckey_expand(unsigned char *sk, const unsigned char *sk_seed);
+int ed25519_ref10_pubkey(unsigned char *pk,const unsigned char *sk);
+int ed25519_ref10_keygen(unsigned char *pk,unsigned char *sk);
+int ed25519_ref10_open(
+ const unsigned char *signature,
+ const unsigned char *m, size_t mlen,
+ const unsigned char *pk);
+int ed25519_ref10_sign(
+ unsigned char *sig,
+ const unsigned char *m, size_t mlen,
+ const unsigned char *sk, const unsigned char *pk);
+
+/* Added in Tor */
+int ed25519_ref10_pubkey_from_curve25519_pubkey(unsigned char *out,
+ const unsigned char *inp,
+ int signbit);
+int ed25519_ref10_blind_secret_key(unsigned char *out,
+ const unsigned char *inp,
+ const unsigned char *param);
+int ed25519_ref10_blind_public_key(unsigned char *out,
+ const unsigned char *inp,
+ const unsigned char *param);
+
+#endif
diff --git a/src/ext/ed25519/ref10/fe.h b/src/ext/ed25519/ref10/fe.h
new file mode 100644
index 0000000000..60c308ba46
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe.h
@@ -0,0 +1,56 @@
+#ifndef FE_H
+#define FE_H
+
+#include "crypto_int32.h"
+
+typedef crypto_int32 fe[10];
+
+/*
+fe means field element.
+Here the field is \Z/(2^255-19).
+An element t, entries t[0]...t[9], represents the integer
+t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
+Bounds on each t[i] vary depending on context.
+*/
+
+#define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes
+#define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes
+#define fe_copy crypto_sign_ed25519_ref10_fe_copy
+#define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero
+#define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative
+#define fe_0 crypto_sign_ed25519_ref10_fe_0
+#define fe_1 crypto_sign_ed25519_ref10_fe_1
+#define fe_cswap crypto_sign_ed25519_ref10_fe_cswap
+#define fe_cmov crypto_sign_ed25519_ref10_fe_cmov
+#define fe_add crypto_sign_ed25519_ref10_fe_add
+#define fe_sub crypto_sign_ed25519_ref10_fe_sub
+#define fe_neg crypto_sign_ed25519_ref10_fe_neg
+#define fe_mul crypto_sign_ed25519_ref10_fe_mul
+#define fe_sq crypto_sign_ed25519_ref10_fe_sq
+#define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2
+#define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666
+#define fe_invert crypto_sign_ed25519_ref10_fe_invert
+#define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523
+
+extern void fe_frombytes(fe,const unsigned char *);
+extern void fe_tobytes(unsigned char *,const fe);
+
+extern void fe_copy(fe,const fe);
+extern int fe_isnonzero(const fe);
+extern int fe_isnegative(const fe);
+extern void fe_0(fe);
+extern void fe_1(fe);
+extern void fe_cswap(fe,fe,unsigned int);
+extern void fe_cmov(fe,const fe,unsigned int);
+
+extern void fe_add(fe,const fe,const fe);
+extern void fe_sub(fe,const fe,const fe);
+extern void fe_neg(fe,const fe);
+extern void fe_mul(fe,const fe,const fe);
+extern void fe_sq(fe,const fe);
+extern void fe_sq2(fe,const fe);
+extern void fe_mul121666(fe,const fe);
+extern void fe_invert(fe,const fe);
+extern void fe_pow22523(fe,const fe);
+
+#endif
diff --git a/src/ext/ed25519/ref10/fe_0.c b/src/ext/ed25519/ref10/fe_0.c
new file mode 100644
index 0000000000..ec879d7337
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_0.c
@@ -0,0 +1,19 @@
+#include "fe.h"
+
+/*
+h = 0
+*/
+
+void fe_0(fe h)
+{
+ h[0] = 0;
+ h[1] = 0;
+ h[2] = 0;
+ h[3] = 0;
+ h[4] = 0;
+ h[5] = 0;
+ h[6] = 0;
+ h[7] = 0;
+ h[8] = 0;
+ h[9] = 0;
+}
diff --git a/src/ext/ed25519/ref10/fe_1.c b/src/ext/ed25519/ref10/fe_1.c
new file mode 100644
index 0000000000..8cf7784844
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_1.c
@@ -0,0 +1,19 @@
+#include "fe.h"
+
+/*
+h = 1
+*/
+
+void fe_1(fe h)
+{
+ h[0] = 1;
+ h[1] = 0;
+ h[2] = 0;
+ h[3] = 0;
+ h[4] = 0;
+ h[5] = 0;
+ h[6] = 0;
+ h[7] = 0;
+ h[8] = 0;
+ h[9] = 0;
+}
diff --git a/src/ext/ed25519/ref10/fe_add.c b/src/ext/ed25519/ref10/fe_add.c
new file mode 100644
index 0000000000..e6a81da202
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_add.c
@@ -0,0 +1,57 @@
+#include "fe.h"
+
+/*
+h = f + g
+Can overlap h with f or g.
+
+Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+
+Postconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+*/
+
+void fe_add(fe h,const fe f,const fe g)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 g0 = g[0];
+ crypto_int32 g1 = g[1];
+ crypto_int32 g2 = g[2];
+ crypto_int32 g3 = g[3];
+ crypto_int32 g4 = g[4];
+ crypto_int32 g5 = g[5];
+ crypto_int32 g6 = g[6];
+ crypto_int32 g7 = g[7];
+ crypto_int32 g8 = g[8];
+ crypto_int32 g9 = g[9];
+ crypto_int32 h0 = f0 + g0;
+ crypto_int32 h1 = f1 + g1;
+ crypto_int32 h2 = f2 + g2;
+ crypto_int32 h3 = f3 + g3;
+ crypto_int32 h4 = f4 + g4;
+ crypto_int32 h5 = f5 + g5;
+ crypto_int32 h6 = f6 + g6;
+ crypto_int32 h7 = f7 + g7;
+ crypto_int32 h8 = f8 + g8;
+ crypto_int32 h9 = f9 + g9;
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_cmov.c b/src/ext/ed25519/ref10/fe_cmov.c
new file mode 100644
index 0000000000..8ca584fb19
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_cmov.c
@@ -0,0 +1,63 @@
+#include "fe.h"
+
+/*
+Replace (f,g) with (g,g) if b == 1;
+replace (f,g) with (f,g) if b == 0.
+
+Preconditions: b in {0,1}.
+*/
+
+void fe_cmov(fe f,const fe g,unsigned int b)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 g0 = g[0];
+ crypto_int32 g1 = g[1];
+ crypto_int32 g2 = g[2];
+ crypto_int32 g3 = g[3];
+ crypto_int32 g4 = g[4];
+ crypto_int32 g5 = g[5];
+ crypto_int32 g6 = g[6];
+ crypto_int32 g7 = g[7];
+ crypto_int32 g8 = g[8];
+ crypto_int32 g9 = g[9];
+ crypto_int32 x0 = f0 ^ g0;
+ crypto_int32 x1 = f1 ^ g1;
+ crypto_int32 x2 = f2 ^ g2;
+ crypto_int32 x3 = f3 ^ g3;
+ crypto_int32 x4 = f4 ^ g4;
+ crypto_int32 x5 = f5 ^ g5;
+ crypto_int32 x6 = f6 ^ g6;
+ crypto_int32 x7 = f7 ^ g7;
+ crypto_int32 x8 = f8 ^ g8;
+ crypto_int32 x9 = f9 ^ g9;
+ b = -b;
+ x0 &= b;
+ x1 &= b;
+ x2 &= b;
+ x3 &= b;
+ x4 &= b;
+ x5 &= b;
+ x6 &= b;
+ x7 &= b;
+ x8 &= b;
+ x9 &= b;
+ f[0] = f0 ^ x0;
+ f[1] = f1 ^ x1;
+ f[2] = f2 ^ x2;
+ f[3] = f3 ^ x3;
+ f[4] = f4 ^ x4;
+ f[5] = f5 ^ x5;
+ f[6] = f6 ^ x6;
+ f[7] = f7 ^ x7;
+ f[8] = f8 ^ x8;
+ f[9] = f9 ^ x9;
+}
diff --git a/src/ext/ed25519/ref10/fe_copy.c b/src/ext/ed25519/ref10/fe_copy.c
new file mode 100644
index 0000000000..9c5bf865a2
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_copy.c
@@ -0,0 +1,29 @@
+#include "fe.h"
+
+/*
+h = f
+*/
+
+void fe_copy(fe h,const fe f)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ h[0] = f0;
+ h[1] = f1;
+ h[2] = f2;
+ h[3] = f3;
+ h[4] = f4;
+ h[5] = f5;
+ h[6] = f6;
+ h[7] = f7;
+ h[8] = f8;
+ h[9] = f9;
+}
diff --git a/src/ext/ed25519/ref10/fe_frombytes.c b/src/ext/ed25519/ref10/fe_frombytes.c
new file mode 100644
index 0000000000..98b8e5f7c1
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_frombytes.c
@@ -0,0 +1,73 @@
+#include "fe.h"
+#include "crypto_int64.h"
+#include "crypto_uint64.h"
+
+static crypto_uint64 load_3(const unsigned char *in)
+{
+ crypto_uint64 result;
+ result = (crypto_uint64) in[0];
+ result |= ((crypto_uint64) in[1]) << 8;
+ result |= ((crypto_uint64) in[2]) << 16;
+ return result;
+}
+
+static crypto_uint64 load_4(const unsigned char *in)
+{
+ crypto_uint64 result;
+ result = (crypto_uint64) in[0];
+ result |= ((crypto_uint64) in[1]) << 8;
+ result |= ((crypto_uint64) in[2]) << 16;
+ result |= ((crypto_uint64) in[3]) << 24;
+ return result;
+}
+
+/*
+Ignores top bit of h.
+*/
+
+void fe_frombytes(fe h,const unsigned char *s)
+{
+ crypto_int64 h0 = load_4(s);
+ crypto_int64 h1 = load_3(s + 4) << 6;
+ crypto_int64 h2 = load_3(s + 7) << 5;
+ crypto_int64 h3 = load_3(s + 10) << 3;
+ crypto_int64 h4 = load_3(s + 13) << 2;
+ crypto_int64 h5 = load_4(s + 16);
+ crypto_int64 h6 = load_3(s + 20) << 7;
+ crypto_int64 h7 = load_3(s + 23) << 5;
+ crypto_int64 h8 = load_3(s + 26) << 4;
+ crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2;
+ crypto_int64 carry0;
+ crypto_int64 carry1;
+ crypto_int64 carry2;
+ crypto_int64 carry3;
+ crypto_int64 carry4;
+ crypto_int64 carry5;
+ crypto_int64 carry6;
+ crypto_int64 carry7;
+ crypto_int64 carry8;
+ crypto_int64 carry9;
+
+ carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= SHL64(carry9,25);
+ carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= SHL64(carry1,25);
+ carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= SHL64(carry3,25);
+ carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= SHL64(carry5,25);
+ carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= SHL64(carry7,25);
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+ carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= SHL64(carry2,26);
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+ carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= SHL64(carry6,26);
+ carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= SHL64(carry8,26);
+
+ h[0] = (crypto_int32) h0;
+ h[1] = (crypto_int32) h1;
+ h[2] = (crypto_int32) h2;
+ h[3] = (crypto_int32) h3;
+ h[4] = (crypto_int32) h4;
+ h[5] = (crypto_int32) h5;
+ h[6] = (crypto_int32) h6;
+ h[7] = (crypto_int32) h7;
+ h[8] = (crypto_int32) h8;
+ h[9] = (crypto_int32) h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_invert.c b/src/ext/ed25519/ref10/fe_invert.c
new file mode 100644
index 0000000000..bcfdb8ff87
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_invert.c
@@ -0,0 +1,14 @@
+#include "fe.h"
+
+void fe_invert(fe out,const fe z)
+{
+ fe t0;
+ fe t1;
+ fe t2;
+ fe t3;
+ int i;
+
+#include "pow225521.h"
+
+ return;
+}
diff --git a/src/ext/ed25519/ref10/fe_isnegative.c b/src/ext/ed25519/ref10/fe_isnegative.c
new file mode 100644
index 0000000000..3b2c8b8d52
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_isnegative.c
@@ -0,0 +1,16 @@
+#include "fe.h"
+
+/*
+return 1 if f is in {1,3,5,...,q-2}
+return 0 if f is in {0,2,4,...,q-1}
+
+Preconditions:
+ |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+*/
+
+int fe_isnegative(const fe f)
+{
+ unsigned char s[32];
+ fe_tobytes(s,f);
+ return s[0] & 1;
+}
diff --git a/src/ext/ed25519/ref10/fe_isnonzero.c b/src/ext/ed25519/ref10/fe_isnonzero.c
new file mode 100644
index 0000000000..47568001ce
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_isnonzero.c
@@ -0,0 +1,19 @@
+#include "fe.h"
+#include "crypto_verify_32.h"
+
+/*
+return 1 if f == 0
+return 0 if f != 0
+
+Preconditions:
+ |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+*/
+
+static const unsigned char zero[32];
+
+int fe_isnonzero(const fe f)
+{
+ unsigned char s[32];
+ fe_tobytes(s,f);
+ return crypto_verify_32(s,zero);
+}
diff --git a/src/ext/ed25519/ref10/fe_mul.c b/src/ext/ed25519/ref10/fe_mul.c
new file mode 100644
index 0000000000..ace63e64c1
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_mul.c
@@ -0,0 +1,253 @@
+#include "fe.h"
+#include "crypto_int64.h"
+
+/*
+h = f * g
+Can overlap h with f or g.
+
+Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+
+Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+*/
+
+/*
+Notes on implementation strategy:
+
+Using schoolbook multiplication.
+Karatsuba would save a little in some cost models.
+
+Most multiplications by 2 and 19 are 32-bit precomputations;
+cheaper than 64-bit postcomputations.
+
+There is one remaining multiplication by 19 in the carry chain;
+one *19 precomputation can be merged into this,
+but the resulting data flow is considerably less clean.
+
+There are 12 carries below.
+10 of them are 2-way parallelizable and vectorizable.
+Can get away with 11 carries, but then data flow is much deeper.
+
+With tighter constraints on inputs can squeeze carries into int32.
+*/
+
+void fe_mul(fe h,const fe f,const fe g)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 g0 = g[0];
+ crypto_int32 g1 = g[1];
+ crypto_int32 g2 = g[2];
+ crypto_int32 g3 = g[3];
+ crypto_int32 g4 = g[4];
+ crypto_int32 g5 = g[5];
+ crypto_int32 g6 = g[6];
+ crypto_int32 g7 = g[7];
+ crypto_int32 g8 = g[8];
+ crypto_int32 g9 = g[9];
+ crypto_int32 g1_19 = 19 * g1; /* 1.959375*2^29 */
+ crypto_int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
+ crypto_int32 g3_19 = 19 * g3;
+ crypto_int32 g4_19 = 19 * g4;
+ crypto_int32 g5_19 = 19 * g5;
+ crypto_int32 g6_19 = 19 * g6;
+ crypto_int32 g7_19 = 19 * g7;
+ crypto_int32 g8_19 = 19 * g8;
+ crypto_int32 g9_19 = 19 * g9;
+ crypto_int32 f1_2 = 2 * f1;
+ crypto_int32 f3_2 = 2 * f3;
+ crypto_int32 f5_2 = 2 * f5;
+ crypto_int32 f7_2 = 2 * f7;
+ crypto_int32 f9_2 = 2 * f9;
+ crypto_int64 f0g0 = f0 * (crypto_int64) g0;
+ crypto_int64 f0g1 = f0 * (crypto_int64) g1;
+ crypto_int64 f0g2 = f0 * (crypto_int64) g2;
+ crypto_int64 f0g3 = f0 * (crypto_int64) g3;
+ crypto_int64 f0g4 = f0 * (crypto_int64) g4;
+ crypto_int64 f0g5 = f0 * (crypto_int64) g5;
+ crypto_int64 f0g6 = f0 * (crypto_int64) g6;
+ crypto_int64 f0g7 = f0 * (crypto_int64) g7;
+ crypto_int64 f0g8 = f0 * (crypto_int64) g8;
+ crypto_int64 f0g9 = f0 * (crypto_int64) g9;
+ crypto_int64 f1g0 = f1 * (crypto_int64) g0;
+ crypto_int64 f1g1_2 = f1_2 * (crypto_int64) g1;
+ crypto_int64 f1g2 = f1 * (crypto_int64) g2;
+ crypto_int64 f1g3_2 = f1_2 * (crypto_int64) g3;
+ crypto_int64 f1g4 = f1 * (crypto_int64) g4;
+ crypto_int64 f1g5_2 = f1_2 * (crypto_int64) g5;
+ crypto_int64 f1g6 = f1 * (crypto_int64) g6;
+ crypto_int64 f1g7_2 = f1_2 * (crypto_int64) g7;
+ crypto_int64 f1g8 = f1 * (crypto_int64) g8;
+ crypto_int64 f1g9_38 = f1_2 * (crypto_int64) g9_19;
+ crypto_int64 f2g0 = f2 * (crypto_int64) g0;
+ crypto_int64 f2g1 = f2 * (crypto_int64) g1;
+ crypto_int64 f2g2 = f2 * (crypto_int64) g2;
+ crypto_int64 f2g3 = f2 * (crypto_int64) g3;
+ crypto_int64 f2g4 = f2 * (crypto_int64) g4;
+ crypto_int64 f2g5 = f2 * (crypto_int64) g5;
+ crypto_int64 f2g6 = f2 * (crypto_int64) g6;
+ crypto_int64 f2g7 = f2 * (crypto_int64) g7;
+ crypto_int64 f2g8_19 = f2 * (crypto_int64) g8_19;
+ crypto_int64 f2g9_19 = f2 * (crypto_int64) g9_19;
+ crypto_int64 f3g0 = f3 * (crypto_int64) g0;
+ crypto_int64 f3g1_2 = f3_2 * (crypto_int64) g1;
+ crypto_int64 f3g2 = f3 * (crypto_int64) g2;
+ crypto_int64 f3g3_2 = f3_2 * (crypto_int64) g3;
+ crypto_int64 f3g4 = f3 * (crypto_int64) g4;
+ crypto_int64 f3g5_2 = f3_2 * (crypto_int64) g5;
+ crypto_int64 f3g6 = f3 * (crypto_int64) g6;
+ crypto_int64 f3g7_38 = f3_2 * (crypto_int64) g7_19;
+ crypto_int64 f3g8_19 = f3 * (crypto_int64) g8_19;
+ crypto_int64 f3g9_38 = f3_2 * (crypto_int64) g9_19;
+ crypto_int64 f4g0 = f4 * (crypto_int64) g0;
+ crypto_int64 f4g1 = f4 * (crypto_int64) g1;
+ crypto_int64 f4g2 = f4 * (crypto_int64) g2;
+ crypto_int64 f4g3 = f4 * (crypto_int64) g3;
+ crypto_int64 f4g4 = f4 * (crypto_int64) g4;
+ crypto_int64 f4g5 = f4 * (crypto_int64) g5;
+ crypto_int64 f4g6_19 = f4 * (crypto_int64) g6_19;
+ crypto_int64 f4g7_19 = f4 * (crypto_int64) g7_19;
+ crypto_int64 f4g8_19 = f4 * (crypto_int64) g8_19;
+ crypto_int64 f4g9_19 = f4 * (crypto_int64) g9_19;
+ crypto_int64 f5g0 = f5 * (crypto_int64) g0;
+ crypto_int64 f5g1_2 = f5_2 * (crypto_int64) g1;
+ crypto_int64 f5g2 = f5 * (crypto_int64) g2;
+ crypto_int64 f5g3_2 = f5_2 * (crypto_int64) g3;
+ crypto_int64 f5g4 = f5 * (crypto_int64) g4;
+ crypto_int64 f5g5_38 = f5_2 * (crypto_int64) g5_19;
+ crypto_int64 f5g6_19 = f5 * (crypto_int64) g6_19;
+ crypto_int64 f5g7_38 = f5_2 * (crypto_int64) g7_19;
+ crypto_int64 f5g8_19 = f5 * (crypto_int64) g8_19;
+ crypto_int64 f5g9_38 = f5_2 * (crypto_int64) g9_19;
+ crypto_int64 f6g0 = f6 * (crypto_int64) g0;
+ crypto_int64 f6g1 = f6 * (crypto_int64) g1;
+ crypto_int64 f6g2 = f6 * (crypto_int64) g2;
+ crypto_int64 f6g3 = f6 * (crypto_int64) g3;
+ crypto_int64 f6g4_19 = f6 * (crypto_int64) g4_19;
+ crypto_int64 f6g5_19 = f6 * (crypto_int64) g5_19;
+ crypto_int64 f6g6_19 = f6 * (crypto_int64) g6_19;
+ crypto_int64 f6g7_19 = f6 * (crypto_int64) g7_19;
+ crypto_int64 f6g8_19 = f6 * (crypto_int64) g8_19;
+ crypto_int64 f6g9_19 = f6 * (crypto_int64) g9_19;
+ crypto_int64 f7g0 = f7 * (crypto_int64) g0;
+ crypto_int64 f7g1_2 = f7_2 * (crypto_int64) g1;
+ crypto_int64 f7g2 = f7 * (crypto_int64) g2;
+ crypto_int64 f7g3_38 = f7_2 * (crypto_int64) g3_19;
+ crypto_int64 f7g4_19 = f7 * (crypto_int64) g4_19;
+ crypto_int64 f7g5_38 = f7_2 * (crypto_int64) g5_19;
+ crypto_int64 f7g6_19 = f7 * (crypto_int64) g6_19;
+ crypto_int64 f7g7_38 = f7_2 * (crypto_int64) g7_19;
+ crypto_int64 f7g8_19 = f7 * (crypto_int64) g8_19;
+ crypto_int64 f7g9_38 = f7_2 * (crypto_int64) g9_19;
+ crypto_int64 f8g0 = f8 * (crypto_int64) g0;
+ crypto_int64 f8g1 = f8 * (crypto_int64) g1;
+ crypto_int64 f8g2_19 = f8 * (crypto_int64) g2_19;
+ crypto_int64 f8g3_19 = f8 * (crypto_int64) g3_19;
+ crypto_int64 f8g4_19 = f8 * (crypto_int64) g4_19;
+ crypto_int64 f8g5_19 = f8 * (crypto_int64) g5_19;
+ crypto_int64 f8g6_19 = f8 * (crypto_int64) g6_19;
+ crypto_int64 f8g7_19 = f8 * (crypto_int64) g7_19;
+ crypto_int64 f8g8_19 = f8 * (crypto_int64) g8_19;
+ crypto_int64 f8g9_19 = f8 * (crypto_int64) g9_19;
+ crypto_int64 f9g0 = f9 * (crypto_int64) g0;
+ crypto_int64 f9g1_38 = f9_2 * (crypto_int64) g1_19;
+ crypto_int64 f9g2_19 = f9 * (crypto_int64) g2_19;
+ crypto_int64 f9g3_38 = f9_2 * (crypto_int64) g3_19;
+ crypto_int64 f9g4_19 = f9 * (crypto_int64) g4_19;
+ crypto_int64 f9g5_38 = f9_2 * (crypto_int64) g5_19;
+ crypto_int64 f9g6_19 = f9 * (crypto_int64) g6_19;
+ crypto_int64 f9g7_38 = f9_2 * (crypto_int64) g7_19;
+ crypto_int64 f9g8_19 = f9 * (crypto_int64) g8_19;
+ crypto_int64 f9g9_38 = f9_2 * (crypto_int64) g9_19;
+ crypto_int64 h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
+ crypto_int64 h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
+ crypto_int64 h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
+ crypto_int64 h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
+ crypto_int64 h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
+ crypto_int64 h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
+ crypto_int64 h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
+ crypto_int64 h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
+ crypto_int64 h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
+ crypto_int64 h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
+ crypto_int64 carry0;
+ crypto_int64 carry1;
+ crypto_int64 carry2;
+ crypto_int64 carry3;
+ crypto_int64 carry4;
+ crypto_int64 carry5;
+ crypto_int64 carry6;
+ crypto_int64 carry7;
+ crypto_int64 carry8;
+ crypto_int64 carry9;
+
+ /*
+ |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
+ i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
+ |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
+ i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
+ */
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+ /* |h0| <= 2^25 */
+ /* |h4| <= 2^25 */
+ /* |h1| <= 1.71*2^59 */
+ /* |h5| <= 1.71*2^59 */
+
+ carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= SHL64(carry1,25);
+ carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= SHL64(carry5,25);
+ /* |h1| <= 2^24; from now on fits into int32 */
+ /* |h5| <= 2^24; from now on fits into int32 */
+ /* |h2| <= 1.41*2^60 */
+ /* |h6| <= 1.41*2^60 */
+
+ carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= SHL64(carry2,26);
+ carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= SHL64(carry6,26);
+ /* |h2| <= 2^25; from now on fits into int32 unchanged */
+ /* |h6| <= 2^25; from now on fits into int32 unchanged */
+ /* |h3| <= 1.71*2^59 */
+ /* |h7| <= 1.71*2^59 */
+
+ carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= SHL64(carry3,25);
+ carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= SHL64(carry7,25);
+ /* |h3| <= 2^24; from now on fits into int32 unchanged */
+ /* |h7| <= 2^24; from now on fits into int32 unchanged */
+ /* |h4| <= 1.72*2^34 */
+ /* |h8| <= 1.41*2^60 */
+
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+ carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= SHL64(carry8,26);
+ /* |h4| <= 2^25; from now on fits into int32 unchanged */
+ /* |h8| <= 2^25; from now on fits into int32 unchanged */
+ /* |h5| <= 1.01*2^24 */
+ /* |h9| <= 1.71*2^59 */
+
+ carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= SHL64(carry9,25);
+ /* |h9| <= 2^24; from now on fits into int32 unchanged */
+ /* |h0| <= 1.1*2^39 */
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+ /* |h0| <= 2^25; from now on fits into int32 unchanged */
+ /* |h1| <= 1.01*2^24 */
+
+ h[0] = (crypto_int32) h0;
+ h[1] = (crypto_int32) h1;
+ h[2] = (crypto_int32) h2;
+ h[3] = (crypto_int32) h3;
+ h[4] = (crypto_int32) h4;
+ h[5] = (crypto_int32) h5;
+ h[6] = (crypto_int32) h6;
+ h[7] = (crypto_int32) h7;
+ h[8] = (crypto_int32) h8;
+ h[9] = (crypto_int32) h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_neg.c b/src/ext/ed25519/ref10/fe_neg.c
new file mode 100644
index 0000000000..2078ce5284
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_neg.c
@@ -0,0 +1,45 @@
+#include "fe.h"
+
+/*
+h = -f
+
+Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+
+Postconditions:
+ |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+*/
+
+void fe_neg(fe h,const fe f)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 h0 = -f0;
+ crypto_int32 h1 = -f1;
+ crypto_int32 h2 = -f2;
+ crypto_int32 h3 = -f3;
+ crypto_int32 h4 = -f4;
+ crypto_int32 h5 = -f5;
+ crypto_int32 h6 = -f6;
+ crypto_int32 h7 = -f7;
+ crypto_int32 h8 = -f8;
+ crypto_int32 h9 = -f9;
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_pow22523.c b/src/ext/ed25519/ref10/fe_pow22523.c
new file mode 100644
index 0000000000..56675a5902
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_pow22523.c
@@ -0,0 +1,13 @@
+#include "fe.h"
+
+void fe_pow22523(fe out,const fe z)
+{
+ fe t0;
+ fe t1;
+ fe t2;
+ int i;
+
+#include "pow22523.h"
+
+ return;
+}
diff --git a/src/ext/ed25519/ref10/fe_sq.c b/src/ext/ed25519/ref10/fe_sq.c
new file mode 100644
index 0000000000..0022a17510
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_sq.c
@@ -0,0 +1,149 @@
+#include "fe.h"
+#include "crypto_int64.h"
+
+/*
+h = f * f
+Can overlap h with f.
+
+Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+
+Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+*/
+
+/*
+See fe_mul.c for discussion of implementation strategy.
+*/
+
+void fe_sq(fe h,const fe f)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 f0_2 = 2 * f0;
+ crypto_int32 f1_2 = 2 * f1;
+ crypto_int32 f2_2 = 2 * f2;
+ crypto_int32 f3_2 = 2 * f3;
+ crypto_int32 f4_2 = 2 * f4;
+ crypto_int32 f5_2 = 2 * f5;
+ crypto_int32 f6_2 = 2 * f6;
+ crypto_int32 f7_2 = 2 * f7;
+ crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */
+ crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */
+ crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */
+ crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */
+ crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */
+ crypto_int64 f0f0 = f0 * (crypto_int64) f0;
+ crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1;
+ crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2;
+ crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3;
+ crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4;
+ crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5;
+ crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6;
+ crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7;
+ crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8;
+ crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9;
+ crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1;
+ crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2;
+ crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2;
+ crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4;
+ crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2;
+ crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6;
+ crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2;
+ crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8;
+ crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38;
+ crypto_int64 f2f2 = f2 * (crypto_int64) f2;
+ crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3;
+ crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4;
+ crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5;
+ crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6;
+ crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7;
+ crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19;
+ crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38;
+ crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3;
+ crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4;
+ crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2;
+ crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6;
+ crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38;
+ crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19;
+ crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38;
+ crypto_int64 f4f4 = f4 * (crypto_int64) f4;
+ crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5;
+ crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19;
+ crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38;
+ crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19;
+ crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38;
+ crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38;
+ crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19;
+ crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38;
+ crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19;
+ crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38;
+ crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19;
+ crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38;
+ crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19;
+ crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38;
+ crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38;
+ crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19;
+ crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38;
+ crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19;
+ crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38;
+ crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38;
+ crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
+ crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
+ crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
+ crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
+ crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
+ crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
+ crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
+ crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
+ crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
+ crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
+ crypto_int64 carry0;
+ crypto_int64 carry1;
+ crypto_int64 carry2;
+ crypto_int64 carry3;
+ crypto_int64 carry4;
+ crypto_int64 carry5;
+ crypto_int64 carry6;
+ crypto_int64 carry7;
+ crypto_int64 carry8;
+ crypto_int64 carry9;
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+
+ carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= SHL64(carry1,25);
+ carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= SHL64(carry5,25);
+
+ carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= SHL64(carry2,26);
+ carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= SHL64(carry6,26);
+
+ carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= SHL64(carry3,25);
+ carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= SHL64(carry7,25);
+
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+ carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= SHL64(carry8,26);
+
+ carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= SHL64(carry9,25);
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+
+ h[0] = (crypto_int32) h0;
+ h[1] = (crypto_int32) h1;
+ h[2] = (crypto_int32) h2;
+ h[3] = (crypto_int32) h3;
+ h[4] = (crypto_int32) h4;
+ h[5] = (crypto_int32) h5;
+ h[6] = (crypto_int32) h6;
+ h[7] = (crypto_int32) h7;
+ h[8] = (crypto_int32) h8;
+ h[9] = (crypto_int32) h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_sq2.c b/src/ext/ed25519/ref10/fe_sq2.c
new file mode 100644
index 0000000000..e8faa69ec9
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_sq2.c
@@ -0,0 +1,160 @@
+#include "fe.h"
+#include "crypto_int64.h"
+
+/*
+h = 2 * f * f
+Can overlap h with f.
+
+Preconditions:
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+
+Postconditions:
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+*/
+
+/*
+See fe_mul.c for discussion of implementation strategy.
+*/
+
+void fe_sq2(fe h,const fe f)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 f0_2 = 2 * f0;
+ crypto_int32 f1_2 = 2 * f1;
+ crypto_int32 f2_2 = 2 * f2;
+ crypto_int32 f3_2 = 2 * f3;
+ crypto_int32 f4_2 = 2 * f4;
+ crypto_int32 f5_2 = 2 * f5;
+ crypto_int32 f6_2 = 2 * f6;
+ crypto_int32 f7_2 = 2 * f7;
+ crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */
+ crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */
+ crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */
+ crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */
+ crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */
+ crypto_int64 f0f0 = f0 * (crypto_int64) f0;
+ crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1;
+ crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2;
+ crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3;
+ crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4;
+ crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5;
+ crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6;
+ crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7;
+ crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8;
+ crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9;
+ crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1;
+ crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2;
+ crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2;
+ crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4;
+ crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2;
+ crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6;
+ crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2;
+ crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8;
+ crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38;
+ crypto_int64 f2f2 = f2 * (crypto_int64) f2;
+ crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3;
+ crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4;
+ crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5;
+ crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6;
+ crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7;
+ crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19;
+ crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38;
+ crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3;
+ crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4;
+ crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2;
+ crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6;
+ crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38;
+ crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19;
+ crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38;
+ crypto_int64 f4f4 = f4 * (crypto_int64) f4;
+ crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5;
+ crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19;
+ crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38;
+ crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19;
+ crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38;
+ crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38;
+ crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19;
+ crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38;
+ crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19;
+ crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38;
+ crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19;
+ crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38;
+ crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19;
+ crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38;
+ crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38;
+ crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19;
+ crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38;
+ crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19;
+ crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38;
+ crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38;
+ crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
+ crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
+ crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
+ crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
+ crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
+ crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
+ crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
+ crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
+ crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
+ crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
+ crypto_int64 carry0;
+ crypto_int64 carry1;
+ crypto_int64 carry2;
+ crypto_int64 carry3;
+ crypto_int64 carry4;
+ crypto_int64 carry5;
+ crypto_int64 carry6;
+ crypto_int64 carry7;
+ crypto_int64 carry8;
+ crypto_int64 carry9;
+
+ h0 += h0;
+ h1 += h1;
+ h2 += h2;
+ h3 += h3;
+ h4 += h4;
+ h5 += h5;
+ h6 += h6;
+ h7 += h7;
+ h8 += h8;
+ h9 += h9;
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+
+ carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= SHL64(carry1,25);
+ carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= SHL64(carry5,25);
+
+ carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= SHL64(carry2,26);
+ carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= SHL64(carry6,26);
+
+ carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= SHL64(carry3,25);
+ carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= SHL64(carry7,25);
+
+ carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= SHL64(carry4,26);
+ carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= SHL64(carry8,26);
+
+ carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= SHL64(carry9,25);
+
+ carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= SHL64(carry0,26);
+
+ h[0] = (crypto_int32) h0;
+ h[1] = (crypto_int32) h1;
+ h[2] = (crypto_int32) h2;
+ h[3] = (crypto_int32) h3;
+ h[4] = (crypto_int32) h4;
+ h[5] = (crypto_int32) h5;
+ h[6] = (crypto_int32) h6;
+ h[7] = (crypto_int32) h7;
+ h[8] = (crypto_int32) h8;
+ h[9] = (crypto_int32) h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_sub.c b/src/ext/ed25519/ref10/fe_sub.c
new file mode 100644
index 0000000000..6e26b7df8f
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_sub.c
@@ -0,0 +1,57 @@
+#include "fe.h"
+
+/*
+h = f - g
+Can overlap h with f or g.
+
+Preconditions:
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+
+Postconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+*/
+
+void fe_sub(fe h,const fe f,const fe g)
+{
+ crypto_int32 f0 = f[0];
+ crypto_int32 f1 = f[1];
+ crypto_int32 f2 = f[2];
+ crypto_int32 f3 = f[3];
+ crypto_int32 f4 = f[4];
+ crypto_int32 f5 = f[5];
+ crypto_int32 f6 = f[6];
+ crypto_int32 f7 = f[7];
+ crypto_int32 f8 = f[8];
+ crypto_int32 f9 = f[9];
+ crypto_int32 g0 = g[0];
+ crypto_int32 g1 = g[1];
+ crypto_int32 g2 = g[2];
+ crypto_int32 g3 = g[3];
+ crypto_int32 g4 = g[4];
+ crypto_int32 g5 = g[5];
+ crypto_int32 g6 = g[6];
+ crypto_int32 g7 = g[7];
+ crypto_int32 g8 = g[8];
+ crypto_int32 g9 = g[9];
+ crypto_int32 h0 = f0 - g0;
+ crypto_int32 h1 = f1 - g1;
+ crypto_int32 h2 = f2 - g2;
+ crypto_int32 h3 = f3 - g3;
+ crypto_int32 h4 = f4 - g4;
+ crypto_int32 h5 = f5 - g5;
+ crypto_int32 h6 = f6 - g6;
+ crypto_int32 h7 = f7 - g7;
+ crypto_int32 h8 = f8 - g8;
+ crypto_int32 h9 = f9 - g9;
+ h[0] = h0;
+ h[1] = h1;
+ h[2] = h2;
+ h[3] = h3;
+ h[4] = h4;
+ h[5] = h5;
+ h[6] = h6;
+ h[7] = h7;
+ h[8] = h8;
+ h[9] = h9;
+}
diff --git a/src/ext/ed25519/ref10/fe_tobytes.c b/src/ext/ed25519/ref10/fe_tobytes.c
new file mode 100644
index 0000000000..3c7f389622
--- /dev/null
+++ b/src/ext/ed25519/ref10/fe_tobytes.c
@@ -0,0 +1,119 @@
+#include "fe.h"
+
+/*
+Preconditions:
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+
+Write p=2^255-19; q=floor(h/p).
+Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+
+Proof:
+ Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+ Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
+
+ Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+ Then 0<y<1.
+
+ Write r=h-pq.
+ Have 0<=r<=p-1=2^255-20.
+ Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
+
+ Write x=r+19(2^-255)r+y.
+ Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
+
+ Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
+ so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
+*/
+
+void fe_tobytes(unsigned char *s,const fe h)
+{
+ crypto_int32 h0 = h[0];
+ crypto_int32 h1 = h[1];
+ crypto_int32 h2 = h[2];
+ crypto_int32 h3 = h[3];
+ crypto_int32 h4 = h[4];
+ crypto_int32 h5 = h[5];
+ crypto_int32 h6 = h[6];
+ crypto_int32 h7 = h[7];
+ crypto_int32 h8 = h[8];
+ crypto_int32 h9 = h[9];
+ crypto_int32 q;
+ crypto_int32 carry0;
+ crypto_int32 carry1;
+ crypto_int32 carry2;
+ crypto_int32 carry3;
+ crypto_int32 carry4;
+ crypto_int32 carry5;
+ crypto_int32 carry6;
+ crypto_int32 carry7;
+ crypto_int32 carry8;
+ crypto_int32 carry9;
+
+ q = (19 * h9 + (((crypto_int32) 1) << 24)) >> 25;
+ q = (h0 + q) >> 26;
+ q = (h1 + q) >> 25;
+ q = (h2 + q) >> 26;
+ q = (h3 + q) >> 25;
+ q = (h4 + q) >> 26;
+ q = (h5 + q) >> 25;
+ q = (h6 + q) >> 26;
+ q = (h7 + q) >> 25;
+ q = (h8 + q) >> 26;
+ q = (h9 + q) >> 25;
+
+ /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
+ h0 += 19 * q;
+ /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
+
+ carry0 = h0 >> 26; h1 += carry0; h0 -= SHL32(carry0,26);
+ carry1 = h1 >> 25; h2 += carry1; h1 -= SHL32(carry1,25);
+ carry2 = h2 >> 26; h3 += carry2; h2 -= SHL32(carry2,26);
+ carry3 = h3 >> 25; h4 += carry3; h3 -= SHL32(carry3,25);
+ carry4 = h4 >> 26; h5 += carry4; h4 -= SHL32(carry4,26);
+ carry5 = h5 >> 25; h6 += carry5; h5 -= SHL32(carry5,25);
+ carry6 = h6 >> 26; h7 += carry6; h6 -= SHL32(carry6,26);
+ carry7 = h7 >> 25; h8 += carry7; h7 -= SHL32(carry7,25);
+ carry8 = h8 >> 26; h9 += carry8; h8 -= SHL32(carry8,26);
+ carry9 = h9 >> 25; h9 -= SHL32(carry9,25);
+ /* h10 = carry9 */
+
+ /*
+ Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
+ Have h0+...+2^230 h9 between 0 and 2^255-1;
+ evidently 2^255 h10-2^255 q = 0.
+ Goal: Output h0+...+2^230 h9.
+ */
+
+ s[0] = h0 >> 0;
+ s[1] = h0 >> 8;
+ s[2] = h0 >> 16;
+ s[3] = (h0 >> 24) | SHL32(h1,2);
+ s[4] = h1 >> 6;
+ s[5] = h1 >> 14;
+ s[6] = (h1 >> 22) | SHL32(h2,3);
+ s[7] = h2 >> 5;
+ s[8] = h2 >> 13;
+ s[9] = (h2 >> 21) | SHL32(h3,5);
+ s[10] = h3 >> 3;
+ s[11] = h3 >> 11;
+ s[12] = (h3 >> 19) | SHL32(h4,6);
+ s[13] = h4 >> 2;
+ s[14] = h4 >> 10;
+ s[15] = h4 >> 18;
+ s[16] = h5 >> 0;
+ s[17] = h5 >> 8;
+ s[18] = h5 >> 16;
+ s[19] = (h5 >> 24) | SHL32(h6,1);
+ s[20] = h6 >> 7;
+ s[21] = h6 >> 15;
+ s[22] = (h6 >> 23) | SHL32(h7,3);
+ s[23] = h7 >> 5;
+ s[24] = h7 >> 13;
+ s[25] = (h7 >> 21) | SHL32(h8,4);
+ s[26] = h8 >> 4;
+ s[27] = h8 >> 12;
+ s[28] = (h8 >> 20) | SHL32(h9,6);
+ s[29] = h9 >> 2;
+ s[30] = h9 >> 10;
+ s[31] = h9 >> 18;
+}
diff --git a/src/ext/ed25519/ref10/ge.h b/src/ext/ed25519/ref10/ge.h
new file mode 100644
index 0000000000..55e95f95b6
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge.h
@@ -0,0 +1,95 @@
+#ifndef GE_H
+#define GE_H
+
+/*
+ge means group element.
+
+Here the group is the set of pairs (x,y) of field elements (see fe.h)
+satisfying -x^2 + y^2 = 1 + d x^2y^2
+where d = -121665/121666.
+
+Representations:
+ ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
+ ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
+ ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
+ ge_precomp (Duif): (y+x,y-x,2dxy)
+*/
+
+#include "fe.h"
+
+typedef struct {
+ fe X;
+ fe Y;
+ fe Z;
+} ge_p2;
+
+typedef struct {
+ fe X;
+ fe Y;
+ fe Z;
+ fe T;
+} ge_p3;
+
+typedef struct {
+ fe X;
+ fe Y;
+ fe Z;
+ fe T;
+} ge_p1p1;
+
+typedef struct {
+ fe yplusx;
+ fe yminusx;
+ fe xy2d;
+} ge_precomp;
+
+typedef struct {
+ fe YplusX;
+ fe YminusX;
+ fe Z;
+ fe T2d;
+} ge_cached;
+
+#define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime
+#define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes
+#define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes
+
+#define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0
+#define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0
+#define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0
+#define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2
+#define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached
+#define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2
+#define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3
+#define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl
+#define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl
+
+#define ge_madd crypto_sign_ed25519_ref10_ge_madd
+#define ge_msub crypto_sign_ed25519_ref10_ge_msub
+#define ge_add crypto_sign_ed25519_ref10_ge_add
+#define ge_sub crypto_sign_ed25519_ref10_ge_sub
+#define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base
+#define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime
+
+extern void ge_tobytes(unsigned char *,const ge_p2 *);
+extern void ge_p3_tobytes(unsigned char *,const ge_p3 *);
+extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *);
+
+extern void ge_p2_0(ge_p2 *);
+extern void ge_p3_0(ge_p3 *);
+extern void ge_precomp_0(ge_precomp *);
+extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *);
+extern void ge_p3_to_cached(ge_cached *,const ge_p3 *);
+extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *);
+extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *);
+extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *);
+extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *);
+
+extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *);
+extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *);
+extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *);
+extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *);
+extern void ge_scalarmult_base(ge_p3 *,const unsigned char *);
+extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *);
+
+#endif
diff --git a/src/ext/ed25519/ref10/ge_add.c b/src/ext/ed25519/ref10/ge_add.c
new file mode 100644
index 0000000000..da7ff5d2eb
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_add.c
@@ -0,0 +1,11 @@
+#include "ge.h"
+
+/*
+r = p + q
+*/
+
+void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)
+{
+ fe t0;
+#include "ge_add.h"
+}
diff --git a/src/ext/ed25519/ref10/ge_add.h b/src/ext/ed25519/ref10/ge_add.h
new file mode 100644
index 0000000000..7481f8ffbe
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_add.h
@@ -0,0 +1,97 @@
+
+/* qhasm: enter ge_add */
+
+/* qhasm: fe X1 */
+
+/* qhasm: fe Y1 */
+
+/* qhasm: fe Z1 */
+
+/* qhasm: fe Z2 */
+
+/* qhasm: fe T1 */
+
+/* qhasm: fe ZZ */
+
+/* qhasm: fe YpX2 */
+
+/* qhasm: fe YmX2 */
+
+/* qhasm: fe T2d2 */
+
+/* qhasm: fe X3 */
+
+/* qhasm: fe Y3 */
+
+/* qhasm: fe Z3 */
+
+/* qhasm: fe T3 */
+
+/* qhasm: fe YpX1 */
+
+/* qhasm: fe YmX1 */
+
+/* qhasm: fe A */
+
+/* qhasm: fe B */
+
+/* qhasm: fe C */
+
+/* qhasm: fe D */
+
+/* qhasm: YpX1 = Y1+X1 */
+/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
+fe_add(r->X,p->Y,p->X);
+
+/* qhasm: YmX1 = Y1-X1 */
+/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
+fe_sub(r->Y,p->Y,p->X);
+
+/* qhasm: A = YpX1*YpX2 */
+/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YpX2=fe#15); */
+/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<YpX2=q->YplusX); */
+fe_mul(r->Z,r->X,q->YplusX);
+
+/* qhasm: B = YmX1*YmX2 */
+/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YmX2=fe#16); */
+/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<YmX2=q->YminusX); */
+fe_mul(r->Y,r->Y,q->YminusX);
+
+/* qhasm: C = T2d2*T1 */
+/* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */
+/* asm 2: fe_mul(>C=r->T,<T2d2=q->T2d,<T1=p->T); */
+fe_mul(r->T,q->T2d,p->T);
+
+/* qhasm: ZZ = Z1*Z2 */
+/* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */
+/* asm 2: fe_mul(>ZZ=r->X,<Z1=p->Z,<Z2=q->Z); */
+fe_mul(r->X,p->Z,q->Z);
+
+/* qhasm: D = 2*ZZ */
+/* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */
+/* asm 2: fe_add(>D=t0,<ZZ=r->X,<ZZ=r->X); */
+fe_add(t0,r->X,r->X);
+
+/* qhasm: X3 = A-B */
+/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
+fe_sub(r->X,r->Z,r->Y);
+
+/* qhasm: Y3 = A+B */
+/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
+fe_add(r->Y,r->Z,r->Y);
+
+/* qhasm: Z3 = D+C */
+/* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_add(>Z3=r->Z,<D=t0,<C=r->T); */
+fe_add(r->Z,t0,r->T);
+
+/* qhasm: T3 = D-C */
+/* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_sub(>T3=r->T,<D=t0,<C=r->T); */
+fe_sub(r->T,t0,r->T);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/ge_add.q b/src/ext/ed25519/ref10/ge_add.q
new file mode 100644
index 0000000000..a6572ab0f8
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_add.q
@@ -0,0 +1,49 @@
+:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->YplusX:q->YminusX:q->Z:q->T2d:
+fe r:var/r=fe:
+
+enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>YpX2=fe#15:>YmX2=fe#16:>Z2=fe#17:>T2d2=fe#18:
+return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
+
+h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
+h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
+h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
+
+:
+
+enter ge_add
+
+fe X1
+fe Y1
+fe Z1
+fe Z2
+fe T1
+fe ZZ
+fe YpX2
+fe YmX2
+fe T2d2
+fe X3
+fe Y3
+fe Z3
+fe T3
+fe YpX1
+fe YmX1
+fe A
+fe B
+fe C
+fe D
+
+YpX1 = Y1+X1
+YmX1 = Y1-X1
+A = YpX1*YpX2
+B = YmX1*YmX2
+C = T2d2*T1
+ZZ = Z1*Z2
+D = 2*ZZ
+X3 = A-B
+Y3 = A+B
+Z3 = D+C
+T3 = D-C
+
+return
diff --git a/src/ext/ed25519/ref10/ge_double_scalarmult.c b/src/ext/ed25519/ref10/ge_double_scalarmult.c
new file mode 100644
index 0000000000..f8bf4bf775
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_double_scalarmult.c
@@ -0,0 +1,96 @@
+#include "ge.h"
+
+static void slide(signed char *r,const unsigned char *a)
+{
+ int i;
+ int b;
+ int k;
+
+ for (i = 0;i < 256;++i)
+ r[i] = 1 & (a[i >> 3] >> (i & 7));
+
+ for (i = 0;i < 256;++i)
+ if (r[i]) {
+ for (b = 1;b <= 6 && i + b < 256;++b) {
+ if (r[i + b]) {
+ if (r[i] + (r[i + b] << b) <= 15) {
+ r[i] += r[i + b] << b; r[i + b] = 0;
+ } else if (r[i] - (r[i + b] << b) >= -15) {
+ r[i] -= r[i + b] << b;
+ for (k = i + b;k < 256;++k) {
+ if (!r[k]) {
+ r[k] = 1;
+ break;
+ }
+ r[k] = 0;
+ }
+ } else
+ break;
+ }
+ }
+ }
+
+}
+
+static ge_precomp Bi[8] = {
+#include "base2.h"
+} ;
+
+/*
+r = a * A + b * B
+where a = a[0]+256*a[1]+...+256^31 a[31].
+and b = b[0]+256*b[1]+...+256^31 b[31].
+B is the Ed25519 base point (x,4/5) with x positive.
+*/
+
+void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b)
+{
+ signed char aslide[256];
+ signed char bslide[256];
+ ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
+ ge_p1p1 t;
+ ge_p3 u;
+ ge_p3 A2;
+ int i;
+
+ slide(aslide,a);
+ slide(bslide,b);
+
+ ge_p3_to_cached(&Ai[0],A);
+ ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
+ ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
+ ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
+ ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
+ ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
+ ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
+ ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
+ ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
+
+ ge_p2_0(r);
+
+ for (i = 255;i >= 0;--i) {
+ if (aslide[i] || bslide[i]) break;
+ }
+
+ for (;i >= 0;--i) {
+ ge_p2_dbl(&t,r);
+
+ if (aslide[i] > 0) {
+ ge_p1p1_to_p3(&u,&t);
+ ge_add(&t,&u,&Ai[aslide[i]/2]);
+ } else if (aslide[i] < 0) {
+ ge_p1p1_to_p3(&u,&t);
+ ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
+ }
+
+ if (bslide[i] > 0) {
+ ge_p1p1_to_p3(&u,&t);
+ ge_madd(&t,&u,&Bi[bslide[i]/2]);
+ } else if (bslide[i] < 0) {
+ ge_p1p1_to_p3(&u,&t);
+ ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
+ }
+
+ ge_p1p1_to_p2(r,&t);
+ }
+}
diff --git a/src/ext/ed25519/ref10/ge_frombytes.c b/src/ext/ed25519/ref10/ge_frombytes.c
new file mode 100644
index 0000000000..1a059ee93f
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_frombytes.c
@@ -0,0 +1,50 @@
+#include "ge.h"
+
+static const fe d = {
+#include "d.h"
+} ;
+
+static const fe sqrtm1 = {
+#include "sqrtm1.h"
+} ;
+
+int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s)
+{
+ fe u;
+ fe v;
+ fe v3;
+ fe vxx;
+ fe check;
+
+ fe_frombytes(h->Y,s);
+ fe_1(h->Z);
+ fe_sq(u,h->Y);
+ fe_mul(v,u,d);
+ fe_sub(u,u,h->Z); /* u = y^2-1 */
+ fe_add(v,v,h->Z); /* v = dy^2+1 */
+
+ fe_sq(v3,v);
+ fe_mul(v3,v3,v); /* v3 = v^3 */
+ fe_sq(h->X,v3);
+ fe_mul(h->X,h->X,v);
+ fe_mul(h->X,h->X,u); /* x = uv^7 */
+
+ fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
+ fe_mul(h->X,h->X,v3);
+ fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */
+
+ fe_sq(vxx,h->X);
+ fe_mul(vxx,vxx,v);
+ fe_sub(check,vxx,u); /* vx^2-u */
+ if (fe_isnonzero(check)) {
+ fe_add(check,vxx,u); /* vx^2+u */
+ if (fe_isnonzero(check)) return -1;
+ fe_mul(h->X,h->X,sqrtm1);
+ }
+
+ if (fe_isnegative(h->X) == (s[31] >> 7))
+ fe_neg(h->X,h->X);
+
+ fe_mul(h->T,h->X,h->Y);
+ return 0;
+}
diff --git a/src/ext/ed25519/ref10/ge_madd.c b/src/ext/ed25519/ref10/ge_madd.c
new file mode 100644
index 0000000000..622571774b
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_madd.c
@@ -0,0 +1,11 @@
+#include "ge.h"
+
+/*
+r = p + q
+*/
+
+void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)
+{
+ fe t0;
+#include "ge_madd.h"
+}
diff --git a/src/ext/ed25519/ref10/ge_madd.h b/src/ext/ed25519/ref10/ge_madd.h
new file mode 100644
index 0000000000..ecae84952b
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_madd.h
@@ -0,0 +1,88 @@
+
+/* qhasm: enter ge_madd */
+
+/* qhasm: fe X1 */
+
+/* qhasm: fe Y1 */
+
+/* qhasm: fe Z1 */
+
+/* qhasm: fe T1 */
+
+/* qhasm: fe ypx2 */
+
+/* qhasm: fe ymx2 */
+
+/* qhasm: fe xy2d2 */
+
+/* qhasm: fe X3 */
+
+/* qhasm: fe Y3 */
+
+/* qhasm: fe Z3 */
+
+/* qhasm: fe T3 */
+
+/* qhasm: fe YpX1 */
+
+/* qhasm: fe YmX1 */
+
+/* qhasm: fe A */
+
+/* qhasm: fe B */
+
+/* qhasm: fe C */
+
+/* qhasm: fe D */
+
+/* qhasm: YpX1 = Y1+X1 */
+/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
+fe_add(r->X,p->Y,p->X);
+
+/* qhasm: YmX1 = Y1-X1 */
+/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
+fe_sub(r->Y,p->Y,p->X);
+
+/* qhasm: A = YpX1*ypx2 */
+/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ypx2=fe#15); */
+/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<ypx2=q->yplusx); */
+fe_mul(r->Z,r->X,q->yplusx);
+
+/* qhasm: B = YmX1*ymx2 */
+/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ymx2=fe#16); */
+/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<ymx2=q->yminusx); */
+fe_mul(r->Y,r->Y,q->yminusx);
+
+/* qhasm: C = xy2d2*T1 */
+/* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */
+/* asm 2: fe_mul(>C=r->T,<xy2d2=q->xy2d,<T1=p->T); */
+fe_mul(r->T,q->xy2d,p->T);
+
+/* qhasm: D = 2*Z1 */
+/* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */
+/* asm 2: fe_add(>D=t0,<Z1=p->Z,<Z1=p->Z); */
+fe_add(t0,p->Z,p->Z);
+
+/* qhasm: X3 = A-B */
+/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
+fe_sub(r->X,r->Z,r->Y);
+
+/* qhasm: Y3 = A+B */
+/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
+fe_add(r->Y,r->Z,r->Y);
+
+/* qhasm: Z3 = D+C */
+/* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_add(>Z3=r->Z,<D=t0,<C=r->T); */
+fe_add(r->Z,t0,r->T);
+
+/* qhasm: T3 = D-C */
+/* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_sub(>T3=r->T,<D=t0,<C=r->T); */
+fe_sub(r->T,t0,r->T);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/ge_madd.q b/src/ext/ed25519/ref10/ge_madd.q
new file mode 100644
index 0000000000..aa3db454e6
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_madd.q
@@ -0,0 +1,46 @@
+:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->yplusx:q->yminusx:q->xy2d:
+fe r:var/r=fe:
+
+enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>ypx2=fe#15:>ymx2=fe#16:>xy2d2=fe#17:
+return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
+
+h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
+h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
+h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
+
+:
+
+enter ge_madd
+
+fe X1
+fe Y1
+fe Z1
+fe T1
+fe ypx2
+fe ymx2
+fe xy2d2
+fe X3
+fe Y3
+fe Z3
+fe T3
+fe YpX1
+fe YmX1
+fe A
+fe B
+fe C
+fe D
+
+YpX1 = Y1+X1
+YmX1 = Y1-X1
+A = YpX1*ypx2
+B = YmX1*ymx2
+C = xy2d2*T1
+D = 2*Z1
+X3 = A-B
+Y3 = A+B
+Z3 = D+C
+T3 = D-C
+
+return
diff --git a/src/ext/ed25519/ref10/ge_msub.c b/src/ext/ed25519/ref10/ge_msub.c
new file mode 100644
index 0000000000..741ecbf113
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_msub.c
@@ -0,0 +1,11 @@
+#include "ge.h"
+
+/*
+r = p - q
+*/
+
+void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)
+{
+ fe t0;
+#include "ge_msub.h"
+}
diff --git a/src/ext/ed25519/ref10/ge_msub.h b/src/ext/ed25519/ref10/ge_msub.h
new file mode 100644
index 0000000000..500f986ba0
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_msub.h
@@ -0,0 +1,88 @@
+
+/* qhasm: enter ge_msub */
+
+/* qhasm: fe X1 */
+
+/* qhasm: fe Y1 */
+
+/* qhasm: fe Z1 */
+
+/* qhasm: fe T1 */
+
+/* qhasm: fe ypx2 */
+
+/* qhasm: fe ymx2 */
+
+/* qhasm: fe xy2d2 */
+
+/* qhasm: fe X3 */
+
+/* qhasm: fe Y3 */
+
+/* qhasm: fe Z3 */
+
+/* qhasm: fe T3 */
+
+/* qhasm: fe YpX1 */
+
+/* qhasm: fe YmX1 */
+
+/* qhasm: fe A */
+
+/* qhasm: fe B */
+
+/* qhasm: fe C */
+
+/* qhasm: fe D */
+
+/* qhasm: YpX1 = Y1+X1 */
+/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
+fe_add(r->X,p->Y,p->X);
+
+/* qhasm: YmX1 = Y1-X1 */
+/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
+fe_sub(r->Y,p->Y,p->X);
+
+/* qhasm: A = YpX1*ymx2 */
+/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ymx2=fe#16); */
+/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<ymx2=q->yminusx); */
+fe_mul(r->Z,r->X,q->yminusx);
+
+/* qhasm: B = YmX1*ypx2 */
+/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ypx2=fe#15); */
+/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<ypx2=q->yplusx); */
+fe_mul(r->Y,r->Y,q->yplusx);
+
+/* qhasm: C = xy2d2*T1 */
+/* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */
+/* asm 2: fe_mul(>C=r->T,<xy2d2=q->xy2d,<T1=p->T); */
+fe_mul(r->T,q->xy2d,p->T);
+
+/* qhasm: D = 2*Z1 */
+/* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */
+/* asm 2: fe_add(>D=t0,<Z1=p->Z,<Z1=p->Z); */
+fe_add(t0,p->Z,p->Z);
+
+/* qhasm: X3 = A-B */
+/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
+fe_sub(r->X,r->Z,r->Y);
+
+/* qhasm: Y3 = A+B */
+/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
+fe_add(r->Y,r->Z,r->Y);
+
+/* qhasm: Z3 = D-C */
+/* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_sub(>Z3=r->Z,<D=t0,<C=r->T); */
+fe_sub(r->Z,t0,r->T);
+
+/* qhasm: T3 = D+C */
+/* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_add(>T3=r->T,<D=t0,<C=r->T); */
+fe_add(r->T,t0,r->T);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/ge_msub.q b/src/ext/ed25519/ref10/ge_msub.q
new file mode 100644
index 0000000000..e3cadd882d
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_msub.q
@@ -0,0 +1,46 @@
+:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->yplusx:q->yminusx:q->xy2d:
+fe r:var/r=fe:
+
+enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>ypx2=fe#15:>ymx2=fe#16:>xy2d2=fe#17:
+return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
+
+h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
+h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
+h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
+
+:
+
+enter ge_msub
+
+fe X1
+fe Y1
+fe Z1
+fe T1
+fe ypx2
+fe ymx2
+fe xy2d2
+fe X3
+fe Y3
+fe Z3
+fe T3
+fe YpX1
+fe YmX1
+fe A
+fe B
+fe C
+fe D
+
+YpX1 = Y1+X1
+YmX1 = Y1-X1
+A = YpX1*ymx2
+B = YmX1*ypx2
+C = xy2d2*T1
+D = 2*Z1
+X3 = A-B
+Y3 = A+B
+Z3 = D-C
+T3 = D+C
+
+return
diff --git a/src/ext/ed25519/ref10/ge_p1p1_to_p2.c b/src/ext/ed25519/ref10/ge_p1p1_to_p2.c
new file mode 100644
index 0000000000..9bb5013d66
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p1p1_to_p2.c
@@ -0,0 +1,12 @@
+#include "ge.h"
+
+/*
+r = p
+*/
+
+extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p)
+{
+ fe_mul(r->X,p->X,p->T);
+ fe_mul(r->Y,p->Y,p->Z);
+ fe_mul(r->Z,p->Z,p->T);
+}
diff --git a/src/ext/ed25519/ref10/ge_p1p1_to_p3.c b/src/ext/ed25519/ref10/ge_p1p1_to_p3.c
new file mode 100644
index 0000000000..2f57b10968
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p1p1_to_p3.c
@@ -0,0 +1,13 @@
+#include "ge.h"
+
+/*
+r = p
+*/
+
+extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p)
+{
+ fe_mul(r->X,p->X,p->T);
+ fe_mul(r->Y,p->Y,p->Z);
+ fe_mul(r->Z,p->Z,p->T);
+ fe_mul(r->T,p->X,p->Y);
+}
diff --git a/src/ext/ed25519/ref10/ge_p2_0.c b/src/ext/ed25519/ref10/ge_p2_0.c
new file mode 100644
index 0000000000..6191d1e6e4
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p2_0.c
@@ -0,0 +1,8 @@
+#include "ge.h"
+
+void ge_p2_0(ge_p2 *h)
+{
+ fe_0(h->X);
+ fe_1(h->Y);
+ fe_1(h->Z);
+}
diff --git a/src/ext/ed25519/ref10/ge_p2_dbl.c b/src/ext/ed25519/ref10/ge_p2_dbl.c
new file mode 100644
index 0000000000..2e332b5cee
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p2_dbl.c
@@ -0,0 +1,11 @@
+#include "ge.h"
+
+/*
+r = 2 * p
+*/
+
+void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p)
+{
+ fe t0;
+#include "ge_p2_dbl.h"
+}
diff --git a/src/ext/ed25519/ref10/ge_p2_dbl.h b/src/ext/ed25519/ref10/ge_p2_dbl.h
new file mode 100644
index 0000000000..128efed907
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p2_dbl.h
@@ -0,0 +1,73 @@
+
+/* qhasm: enter ge_p2_dbl */
+
+/* qhasm: fe X1 */
+
+/* qhasm: fe Y1 */
+
+/* qhasm: fe Z1 */
+
+/* qhasm: fe A */
+
+/* qhasm: fe AA */
+
+/* qhasm: fe XX */
+
+/* qhasm: fe YY */
+
+/* qhasm: fe B */
+
+/* qhasm: fe X3 */
+
+/* qhasm: fe Y3 */
+
+/* qhasm: fe Z3 */
+
+/* qhasm: fe T3 */
+
+/* qhasm: XX=X1^2 */
+/* asm 1: fe_sq(>XX=fe#1,<X1=fe#11); */
+/* asm 2: fe_sq(>XX=r->X,<X1=p->X); */
+fe_sq(r->X,p->X);
+
+/* qhasm: YY=Y1^2 */
+/* asm 1: fe_sq(>YY=fe#3,<Y1=fe#12); */
+/* asm 2: fe_sq(>YY=r->Z,<Y1=p->Y); */
+fe_sq(r->Z,p->Y);
+
+/* qhasm: B=2*Z1^2 */
+/* asm 1: fe_sq2(>B=fe#4,<Z1=fe#13); */
+/* asm 2: fe_sq2(>B=r->T,<Z1=p->Z); */
+fe_sq2(r->T,p->Z);
+
+/* qhasm: A=X1+Y1 */
+/* asm 1: fe_add(>A=fe#2,<X1=fe#11,<Y1=fe#12); */
+/* asm 2: fe_add(>A=r->Y,<X1=p->X,<Y1=p->Y); */
+fe_add(r->Y,p->X,p->Y);
+
+/* qhasm: AA=A^2 */
+/* asm 1: fe_sq(>AA=fe#5,<A=fe#2); */
+/* asm 2: fe_sq(>AA=t0,<A=r->Y); */
+fe_sq(t0,r->Y);
+
+/* qhasm: Y3=YY+XX */
+/* asm 1: fe_add(>Y3=fe#2,<YY=fe#3,<XX=fe#1); */
+/* asm 2: fe_add(>Y3=r->Y,<YY=r->Z,<XX=r->X); */
+fe_add(r->Y,r->Z,r->X);
+
+/* qhasm: Z3=YY-XX */
+/* asm 1: fe_sub(>Z3=fe#3,<YY=fe#3,<XX=fe#1); */
+/* asm 2: fe_sub(>Z3=r->Z,<YY=r->Z,<XX=r->X); */
+fe_sub(r->Z,r->Z,r->X);
+
+/* qhasm: X3=AA-Y3 */
+/* asm 1: fe_sub(>X3=fe#1,<AA=fe#5,<Y3=fe#2); */
+/* asm 2: fe_sub(>X3=r->X,<AA=t0,<Y3=r->Y); */
+fe_sub(r->X,t0,r->Y);
+
+/* qhasm: T3=B-Z3 */
+/* asm 1: fe_sub(>T3=fe#4,<B=fe#4,<Z3=fe#3); */
+/* asm 2: fe_sub(>T3=r->T,<B=r->T,<Z3=r->Z); */
+fe_sub(r->T,r->T,r->Z);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/ge_p2_dbl.q b/src/ext/ed25519/ref10/ge_p2_dbl.q
new file mode 100644
index 0000000000..170d42f9a7
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p2_dbl.q
@@ -0,0 +1,41 @@
+:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:
+fe r:var/r=fe:
+
+enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:
+return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
+
+h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
+h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
+h=2*f^2:<f=fe:>h=fe:asm/fe_sq2(>h,<f);:
+h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
+
+:
+
+enter ge_p2_dbl
+
+fe X1
+fe Y1
+fe Z1
+fe A
+fe AA
+fe XX
+fe YY
+fe B
+fe X3
+fe Y3
+fe Z3
+fe T3
+
+XX=X1^2
+YY=Y1^2
+B=2*Z1^2
+A=X1+Y1
+AA=A^2
+Y3=YY+XX
+Z3=YY-XX
+X3=AA-Y3
+T3=B-Z3
+
+return
diff --git a/src/ext/ed25519/ref10/ge_p3_0.c b/src/ext/ed25519/ref10/ge_p3_0.c
new file mode 100644
index 0000000000..401b2935a1
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p3_0.c
@@ -0,0 +1,9 @@
+#include "ge.h"
+
+void ge_p3_0(ge_p3 *h)
+{
+ fe_0(h->X);
+ fe_1(h->Y);
+ fe_1(h->Z);
+ fe_0(h->T);
+}
diff --git a/src/ext/ed25519/ref10/ge_p3_dbl.c b/src/ext/ed25519/ref10/ge_p3_dbl.c
new file mode 100644
index 0000000000..0d8a05915d
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p3_dbl.c
@@ -0,0 +1,12 @@
+#include "ge.h"
+
+/*
+r = 2 * p
+*/
+
+void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p)
+{
+ ge_p2 q;
+ ge_p3_to_p2(&q,p);
+ ge_p2_dbl(r,&q);
+}
diff --git a/src/ext/ed25519/ref10/ge_p3_to_cached.c b/src/ext/ed25519/ref10/ge_p3_to_cached.c
new file mode 100644
index 0000000000..bde64228cf
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p3_to_cached.c
@@ -0,0 +1,17 @@
+#include "ge.h"
+
+/*
+r = p
+*/
+
+static const fe d2 = {
+#include "d2.h"
+} ;
+
+extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p)
+{
+ fe_add(r->YplusX,p->Y,p->X);
+ fe_sub(r->YminusX,p->Y,p->X);
+ fe_copy(r->Z,p->Z);
+ fe_mul(r->T2d,p->T,d2);
+}
diff --git a/src/ext/ed25519/ref10/ge_p3_to_p2.c b/src/ext/ed25519/ref10/ge_p3_to_p2.c
new file mode 100644
index 0000000000..e532a9e4cb
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p3_to_p2.c
@@ -0,0 +1,12 @@
+#include "ge.h"
+
+/*
+r = p
+*/
+
+extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p)
+{
+ fe_copy(r->X,p->X);
+ fe_copy(r->Y,p->Y);
+ fe_copy(r->Z,p->Z);
+}
diff --git a/src/ext/ed25519/ref10/ge_p3_tobytes.c b/src/ext/ed25519/ref10/ge_p3_tobytes.c
new file mode 100644
index 0000000000..21cb2fc656
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_p3_tobytes.c
@@ -0,0 +1,14 @@
+#include "ge.h"
+
+void ge_p3_tobytes(unsigned char *s,const ge_p3 *h)
+{
+ fe recip;
+ fe x;
+ fe y;
+
+ fe_invert(recip,h->Z);
+ fe_mul(x,h->X,recip);
+ fe_mul(y,h->Y,recip);
+ fe_tobytes(s,y);
+ s[31] ^= fe_isnegative(x) << 7;
+}
diff --git a/src/ext/ed25519/ref10/ge_precomp_0.c b/src/ext/ed25519/ref10/ge_precomp_0.c
new file mode 100644
index 0000000000..2e218861d8
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_precomp_0.c
@@ -0,0 +1,8 @@
+#include "ge.h"
+
+void ge_precomp_0(ge_precomp *h)
+{
+ fe_1(h->yplusx);
+ fe_1(h->yminusx);
+ fe_0(h->xy2d);
+}
diff --git a/src/ext/ed25519/ref10/ge_scalarmult_base.c b/src/ext/ed25519/ref10/ge_scalarmult_base.c
new file mode 100644
index 0000000000..5292f83221
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_scalarmult_base.c
@@ -0,0 +1,109 @@
+#include "ge.h"
+#include "crypto_uint32.h"
+
+/* Rename this so as not to interfere with select() which torint.h apparently
+ * grabs. :p */
+#define select ed25519_ref10_select
+
+static unsigned char equal(signed char b,signed char c)
+{
+ unsigned char ub = b;
+ unsigned char uc = c;
+ unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
+ crypto_uint32 y = x; /* 0: yes; 1..255: no */
+ y -= 1; /* 4294967295: yes; 0..254: no */
+ y >>= 31; /* 1: yes; 0: no */
+ return y;
+}
+
+static unsigned char negative(signed char b)
+{
+ uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
+ x >>= 63; /* 1: yes; 0: no */
+ return x;
+}
+
+static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b)
+{
+ fe_cmov(t->yplusx,u->yplusx,b);
+ fe_cmov(t->yminusx,u->yminusx,b);
+ fe_cmov(t->xy2d,u->xy2d,b);
+}
+
+/* base[i][j] = (j+1)*256^i*B */
+static ge_precomp base[32][8] = {
+#include "base.h"
+} ;
+
+static void select(ge_precomp *t,int pos,signed char b)
+{
+ ge_precomp minust;
+ unsigned char bnegative = negative(b);
+ unsigned char babs = b - SHL8( (-bnegative) & (unsigned char)b, 1);
+
+ ge_precomp_0(t);
+ cmov(t,&base[pos][0],equal(babs,1));
+ cmov(t,&base[pos][1],equal(babs,2));
+ cmov(t,&base[pos][2],equal(babs,3));
+ cmov(t,&base[pos][3],equal(babs,4));
+ cmov(t,&base[pos][4],equal(babs,5));
+ cmov(t,&base[pos][5],equal(babs,6));
+ cmov(t,&base[pos][6],equal(babs,7));
+ cmov(t,&base[pos][7],equal(babs,8));
+ fe_copy(minust.yplusx,t->yminusx);
+ fe_copy(minust.yminusx,t->yplusx);
+ fe_neg(minust.xy2d,t->xy2d);
+ cmov(t,&minust,bnegative);
+}
+
+/*
+h = a * B
+where a = a[0]+256*a[1]+...+256^31 a[31]
+B is the Ed25519 base point (x,4/5) with x positive.
+
+Preconditions:
+ a[31] <= 127
+*/
+
+void ge_scalarmult_base(ge_p3 *h,const unsigned char *a)
+{
+ signed char e[64];
+ signed char carry;
+ ge_p1p1 r;
+ ge_p2 s;
+ ge_precomp t;
+ int i;
+
+ for (i = 0;i < 32;++i) {
+ e[2 * i + 0] = (a[i] >> 0) & 15;
+ e[2 * i + 1] = (a[i] >> 4) & 15;
+ }
+ /* each e[i] is between 0 and 15 */
+ /* e[63] is between 0 and 7 */
+
+ carry = 0;
+ for (i = 0;i < 63;++i) {
+ e[i] += carry;
+ carry = e[i] + 8;
+ carry >>= 4;
+ e[i] -= SHL8(carry,4);
+ }
+ e[63] += carry;
+ /* each e[i] is between -8 and 8 */
+
+ ge_p3_0(h);
+ for (i = 1;i < 64;i += 2) {
+ select(&t,i / 2,e[i]);
+ ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
+ }
+
+ ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r);
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r);
+
+ for (i = 0;i < 64;i += 2) {
+ select(&t,i / 2,e[i]);
+ ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
+ }
+}
diff --git a/src/ext/ed25519/ref10/ge_sub.c b/src/ext/ed25519/ref10/ge_sub.c
new file mode 100644
index 0000000000..69f3d54062
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_sub.c
@@ -0,0 +1,11 @@
+#include "ge.h"
+
+/*
+r = p - q
+*/
+
+void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)
+{
+ fe t0;
+#include "ge_sub.h"
+}
diff --git a/src/ext/ed25519/ref10/ge_sub.h b/src/ext/ed25519/ref10/ge_sub.h
new file mode 100644
index 0000000000..b4ef1f5dd0
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_sub.h
@@ -0,0 +1,97 @@
+
+/* qhasm: enter ge_sub */
+
+/* qhasm: fe X1 */
+
+/* qhasm: fe Y1 */
+
+/* qhasm: fe Z1 */
+
+/* qhasm: fe Z2 */
+
+/* qhasm: fe T1 */
+
+/* qhasm: fe ZZ */
+
+/* qhasm: fe YpX2 */
+
+/* qhasm: fe YmX2 */
+
+/* qhasm: fe T2d2 */
+
+/* qhasm: fe X3 */
+
+/* qhasm: fe Y3 */
+
+/* qhasm: fe Z3 */
+
+/* qhasm: fe T3 */
+
+/* qhasm: fe YpX1 */
+
+/* qhasm: fe YmX1 */
+
+/* qhasm: fe A */
+
+/* qhasm: fe B */
+
+/* qhasm: fe C */
+
+/* qhasm: fe D */
+
+/* qhasm: YpX1 = Y1+X1 */
+/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
+fe_add(r->X,p->Y,p->X);
+
+/* qhasm: YmX1 = Y1-X1 */
+/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
+/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
+fe_sub(r->Y,p->Y,p->X);
+
+/* qhasm: A = YpX1*YmX2 */
+/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YmX2=fe#16); */
+/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<YmX2=q->YminusX); */
+fe_mul(r->Z,r->X,q->YminusX);
+
+/* qhasm: B = YmX1*YpX2 */
+/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YpX2=fe#15); */
+/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<YpX2=q->YplusX); */
+fe_mul(r->Y,r->Y,q->YplusX);
+
+/* qhasm: C = T2d2*T1 */
+/* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */
+/* asm 2: fe_mul(>C=r->T,<T2d2=q->T2d,<T1=p->T); */
+fe_mul(r->T,q->T2d,p->T);
+
+/* qhasm: ZZ = Z1*Z2 */
+/* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */
+/* asm 2: fe_mul(>ZZ=r->X,<Z1=p->Z,<Z2=q->Z); */
+fe_mul(r->X,p->Z,q->Z);
+
+/* qhasm: D = 2*ZZ */
+/* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */
+/* asm 2: fe_add(>D=t0,<ZZ=r->X,<ZZ=r->X); */
+fe_add(t0,r->X,r->X);
+
+/* qhasm: X3 = A-B */
+/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
+fe_sub(r->X,r->Z,r->Y);
+
+/* qhasm: Y3 = A+B */
+/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
+/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
+fe_add(r->Y,r->Z,r->Y);
+
+/* qhasm: Z3 = D-C */
+/* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_sub(>Z3=r->Z,<D=t0,<C=r->T); */
+fe_sub(r->Z,t0,r->T);
+
+/* qhasm: T3 = D+C */
+/* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */
+/* asm 2: fe_add(>T3=r->T,<D=t0,<C=r->T); */
+fe_add(r->T,t0,r->T);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/ge_sub.q b/src/ext/ed25519/ref10/ge_sub.q
new file mode 100644
index 0000000000..2779a4a201
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_sub.q
@@ -0,0 +1,49 @@
+:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->YplusX:q->YminusX:q->Z:q->T2d:
+fe r:var/r=fe:
+
+enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>YpX2=fe#15:>YmX2=fe#16:>Z2=fe#17:>T2d2=fe#18:
+return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
+
+h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
+h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
+h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
+
+:
+
+enter ge_sub
+
+fe X1
+fe Y1
+fe Z1
+fe Z2
+fe T1
+fe ZZ
+fe YpX2
+fe YmX2
+fe T2d2
+fe X3
+fe Y3
+fe Z3
+fe T3
+fe YpX1
+fe YmX1
+fe A
+fe B
+fe C
+fe D
+
+YpX1 = Y1+X1
+YmX1 = Y1-X1
+A = YpX1*YmX2
+B = YmX1*YpX2
+C = T2d2*T1
+ZZ = Z1*Z2
+D = 2*ZZ
+X3 = A-B
+Y3 = A+B
+Z3 = D-C
+T3 = D+C
+
+return
diff --git a/src/ext/ed25519/ref10/ge_tobytes.c b/src/ext/ed25519/ref10/ge_tobytes.c
new file mode 100644
index 0000000000..31b3d33e09
--- /dev/null
+++ b/src/ext/ed25519/ref10/ge_tobytes.c
@@ -0,0 +1,14 @@
+#include "ge.h"
+
+void ge_tobytes(unsigned char *s,const ge_p2 *h)
+{
+ fe recip;
+ fe x;
+ fe y;
+
+ fe_invert(recip,h->Z);
+ fe_mul(x,h->X,recip);
+ fe_mul(y,h->Y,recip);
+ fe_tobytes(s,y);
+ s[31] ^= fe_isnegative(x) << 7;
+}
diff --git a/src/ext/ed25519/ref10/keyconv.c b/src/ext/ed25519/ref10/keyconv.c
new file mode 100644
index 0000000000..854b150d69
--- /dev/null
+++ b/src/ext/ed25519/ref10/keyconv.c
@@ -0,0 +1,37 @@
+/* Added to ref10 for Tor. We place this in the public domain. Alternatively,
+ * you may have it under the Creative Commons 0 "CC0" license. */
+#include "fe.h"
+#include "ed25519_ref10.h"
+
+int ed25519_ref10_pubkey_from_curve25519_pubkey(unsigned char *out,
+ const unsigned char *inp,
+ int signbit)
+{
+ fe u;
+ fe one;
+ fe y;
+ fe uplus1;
+ fe uminus1;
+ fe inv_uplus1;
+
+ /* From prop228:
+
+ Given a curve25519 x-coordinate (u), we can get the y coordinate
+ of the ed25519 key using
+
+ y = (u-1)/(u+1)
+ */
+ fe_frombytes(u, inp);
+ fe_1(one);
+ fe_sub(uminus1, u, one);
+ fe_add(uplus1, u, one);
+ fe_invert(inv_uplus1, uplus1);
+ fe_mul(y, uminus1, inv_uplus1);
+
+ fe_tobytes(out, y);
+
+ /* propagate sign. */
+ out[31] |= (!!signbit) << 7;
+
+ return 0;
+}
diff --git a/src/ext/ed25519/ref10/keypair.c b/src/ext/ed25519/ref10/keypair.c
new file mode 100644
index 0000000000..7ddbaa971e
--- /dev/null
+++ b/src/ext/ed25519/ref10/keypair.c
@@ -0,0 +1,51 @@
+/* Modified for Tor: new API, 64-byte secret keys. */
+#include <string.h>
+#include "randombytes.h"
+#include "crypto_sign.h"
+#include "crypto_hash_sha512.h"
+#include "ge.h"
+
+int
+crypto_sign_seckey(unsigned char *sk)
+{
+ unsigned char seed[32];
+
+ if (randombytes(seed,32) < 0)
+ return -1;
+
+ crypto_sign_seckey_expand(sk, seed);
+
+ memwipe(seed, 0, 32);
+
+ return 0;
+}
+
+int crypto_sign_seckey_expand(unsigned char *sk, const unsigned char *skseed)
+{
+ crypto_hash_sha512(sk,skseed,32);
+ sk[0] &= 248;
+ sk[31] &= 63;
+ sk[31] |= 64;
+
+ return 0;
+}
+
+int crypto_sign_pubkey(unsigned char *pk,const unsigned char *sk)
+{
+ ge_p3 A;
+
+ ge_scalarmult_base(&A,sk);
+ ge_p3_tobytes(pk,&A);
+
+ return 0;
+}
+
+
+int crypto_sign_keypair(unsigned char *pk,unsigned char *sk)
+{
+ crypto_sign_seckey(sk);
+ crypto_sign_pubkey(pk, sk);
+
+ return 0;
+}
+
diff --git a/src/ext/ed25519/ref10/open.c b/src/ext/ed25519/ref10/open.c
new file mode 100644
index 0000000000..9dbeb4cdd0
--- /dev/null
+++ b/src/ext/ed25519/ref10/open.c
@@ -0,0 +1,42 @@
+/* (Modified by Tor to verify signature separately from message) */
+#include <string.h>
+#include "crypto_sign.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_32.h"
+#include "ge.h"
+#include "sc.h"
+
+/* 'signature' must be 64-bytes long. */
+int crypto_sign_open(
+ const unsigned char *signature,
+ const unsigned char *m, size_t mlen,
+ const unsigned char *pk
+)
+{
+ unsigned char pkcopy[32];
+ unsigned char rcopy[32];
+ unsigned char scopy[32];
+ unsigned char h[64];
+ unsigned char rcheck[32];
+ ge_p3 A;
+ ge_p2 R;
+
+ if (signature[63] & 224) goto badsig;
+ if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;
+
+ memmove(pkcopy,pk,32);
+ memmove(rcopy,signature,32);
+ memmove(scopy,signature + 32,32);
+
+ crypto_hash_sha512_3(h, rcopy, 32, pkcopy, 32, m, mlen);
+ sc_reduce(h);
+
+ ge_double_scalarmult_vartime(&R,h,&A,scopy);
+ ge_tobytes(rcheck,&R);
+ if (crypto_verify_32(rcheck,rcopy) == 0) {
+ return 0;
+ }
+
+badsig:
+ return -1;
+}
diff --git a/src/ext/ed25519/ref10/pow22523.h b/src/ext/ed25519/ref10/pow22523.h
new file mode 100644
index 0000000000..9204ff838f
--- /dev/null
+++ b/src/ext/ed25519/ref10/pow22523.h
@@ -0,0 +1,161 @@
+/* Modified by Tor: pointless loops removed to appease analysis tools */
+
+/* qhasm: fe z1 */
+
+/* qhasm: fe z2 */
+
+/* qhasm: fe z8 */
+
+/* qhasm: fe z9 */
+
+/* qhasm: fe z11 */
+
+/* qhasm: fe z22 */
+
+/* qhasm: fe z_5_0 */
+
+/* qhasm: fe z_10_5 */
+
+/* qhasm: fe z_10_0 */
+
+/* qhasm: fe z_20_10 */
+
+/* qhasm: fe z_20_0 */
+
+/* qhasm: fe z_40_20 */
+
+/* qhasm: fe z_40_0 */
+
+/* qhasm: fe z_50_10 */
+
+/* qhasm: fe z_50_0 */
+
+/* qhasm: fe z_100_50 */
+
+/* qhasm: fe z_100_0 */
+
+/* qhasm: fe z_200_100 */
+
+/* qhasm: fe z_200_0 */
+
+/* qhasm: fe z_250_50 */
+
+/* qhasm: fe z_250_0 */
+
+/* qhasm: fe z_252_2 */
+
+/* qhasm: fe z_252_3 */
+
+/* qhasm: enter pow22523 */
+
+/* qhasm: z2 = z1^2^1 */
+/* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */
+/* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */
+fe_sq(t0,z); /* DEADCODE This loop has no effect: for (i = 1;i < 1;++i) fe_sq(t0,t0); */
+
+/* qhasm: z8 = z2^2^2 */
+/* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */
+/* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */
+fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
+
+/* qhasm: z9 = z1*z8 */
+/* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */
+/* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */
+fe_mul(t1,z,t1);
+
+/* qhasm: z11 = z2*z9 */
+/* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */
+/* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */
+fe_mul(t0,t0,t1);
+
+/* qhasm: z22 = z11^2^1 */
+/* asm 1: fe_sq(>z22=fe#1,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#1,>z22=fe#1); */
+/* asm 2: fe_sq(>z22=t0,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t0,>z22=t0); */
+fe_sq(t0,t0); /* DEADCODE This loop has no effect: for (i = 1;i < 1;++i) fe_sq(t0,t0); */
+
+/* qhasm: z_5_0 = z9*z22 */
+/* asm 1: fe_mul(>z_5_0=fe#1,<z9=fe#2,<z22=fe#1); */
+/* asm 2: fe_mul(>z_5_0=t0,<z9=t1,<z22=t0); */
+fe_mul(t0,t1,t0);
+
+/* qhasm: z_10_5 = z_5_0^2^5 */
+/* asm 1: fe_sq(>z_10_5=fe#2,<z_5_0=fe#1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#2,>z_10_5=fe#2); */
+/* asm 2: fe_sq(>z_10_5=t1,<z_5_0=t0); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t1,>z_10_5=t1); */
+fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1);
+
+/* qhasm: z_10_0 = z_10_5*z_5_0 */
+/* asm 1: fe_mul(>z_10_0=fe#1,<z_10_5=fe#2,<z_5_0=fe#1); */
+/* asm 2: fe_mul(>z_10_0=t0,<z_10_5=t1,<z_5_0=t0); */
+fe_mul(t0,t1,t0);
+
+/* qhasm: z_20_10 = z_10_0^2^10 */
+/* asm 1: fe_sq(>z_20_10=fe#2,<z_10_0=fe#1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#2,>z_20_10=fe#2); */
+/* asm 2: fe_sq(>z_20_10=t1,<z_10_0=t0); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t1,>z_20_10=t1); */
+fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1);
+
+/* qhasm: z_20_0 = z_20_10*z_10_0 */
+/* asm 1: fe_mul(>z_20_0=fe#2,<z_20_10=fe#2,<z_10_0=fe#1); */
+/* asm 2: fe_mul(>z_20_0=t1,<z_20_10=t1,<z_10_0=t0); */
+fe_mul(t1,t1,t0);
+
+/* qhasm: z_40_20 = z_20_0^2^20 */
+/* asm 1: fe_sq(>z_40_20=fe#3,<z_20_0=fe#2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#3,>z_40_20=fe#3); */
+/* asm 2: fe_sq(>z_40_20=t2,<z_20_0=t1); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t2,>z_40_20=t2); */
+fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2);
+
+/* qhasm: z_40_0 = z_40_20*z_20_0 */
+/* asm 1: fe_mul(>z_40_0=fe#2,<z_40_20=fe#3,<z_20_0=fe#2); */
+/* asm 2: fe_mul(>z_40_0=t1,<z_40_20=t2,<z_20_0=t1); */
+fe_mul(t1,t2,t1);
+
+/* qhasm: z_50_10 = z_40_0^2^10 */
+/* asm 1: fe_sq(>z_50_10=fe#2,<z_40_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#2,>z_50_10=fe#2); */
+/* asm 2: fe_sq(>z_50_10=t1,<z_40_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t1,>z_50_10=t1); */
+fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1);
+
+/* qhasm: z_50_0 = z_50_10*z_10_0 */
+/* asm 1: fe_mul(>z_50_0=fe#1,<z_50_10=fe#2,<z_10_0=fe#1); */
+/* asm 2: fe_mul(>z_50_0=t0,<z_50_10=t1,<z_10_0=t0); */
+fe_mul(t0,t1,t0);
+
+/* qhasm: z_100_50 = z_50_0^2^50 */
+/* asm 1: fe_sq(>z_100_50=fe#2,<z_50_0=fe#1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#2,>z_100_50=fe#2); */
+/* asm 2: fe_sq(>z_100_50=t1,<z_50_0=t0); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t1,>z_100_50=t1); */
+fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1);
+
+/* qhasm: z_100_0 = z_100_50*z_50_0 */
+/* asm 1: fe_mul(>z_100_0=fe#2,<z_100_50=fe#2,<z_50_0=fe#1); */
+/* asm 2: fe_mul(>z_100_0=t1,<z_100_50=t1,<z_50_0=t0); */
+fe_mul(t1,t1,t0);
+
+/* qhasm: z_200_100 = z_100_0^2^100 */
+/* asm 1: fe_sq(>z_200_100=fe#3,<z_100_0=fe#2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#3,>z_200_100=fe#3); */
+/* asm 2: fe_sq(>z_200_100=t2,<z_100_0=t1); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t2,>z_200_100=t2); */
+fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2);
+
+/* qhasm: z_200_0 = z_200_100*z_100_0 */
+/* asm 1: fe_mul(>z_200_0=fe#2,<z_200_100=fe#3,<z_100_0=fe#2); */
+/* asm 2: fe_mul(>z_200_0=t1,<z_200_100=t2,<z_100_0=t1); */
+fe_mul(t1,t2,t1);
+
+/* qhasm: z_250_50 = z_200_0^2^50 */
+/* asm 1: fe_sq(>z_250_50=fe#2,<z_200_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#2,>z_250_50=fe#2); */
+/* asm 2: fe_sq(>z_250_50=t1,<z_200_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t1,>z_250_50=t1); */
+fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1);
+
+/* qhasm: z_250_0 = z_250_50*z_50_0 */
+/* asm 1: fe_mul(>z_250_0=fe#1,<z_250_50=fe#2,<z_50_0=fe#1); */
+/* asm 2: fe_mul(>z_250_0=t0,<z_250_50=t1,<z_50_0=t0); */
+fe_mul(t0,t1,t0);
+
+/* qhasm: z_252_2 = z_250_0^2^2 */
+/* asm 1: fe_sq(>z_252_2=fe#1,<z_250_0=fe#1); for (i = 1;i < 2;++i) fe_sq(>z_252_2=fe#1,>z_252_2=fe#1); */
+/* asm 2: fe_sq(>z_252_2=t0,<z_250_0=t0); for (i = 1;i < 2;++i) fe_sq(>z_252_2=t0,>z_252_2=t0); */
+fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0);
+
+/* qhasm: z_252_3 = z_252_2*z1 */
+/* asm 1: fe_mul(>z_252_3=fe#12,<z_252_2=fe#1,<z1=fe#11); */
+/* asm 2: fe_mul(>z_252_3=out,<z_252_2=t0,<z1=z); */
+fe_mul(out,t0,z);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/pow22523.q b/src/ext/ed25519/ref10/pow22523.q
new file mode 100644
index 0000000000..2ce1da9d4d
--- /dev/null
+++ b/src/ext/ed25519/ref10/pow22523.q
@@ -0,0 +1,61 @@
+:name:fe:t0:t1:t2:t3:t4:t5:t6:t7:t8:t9:z:out:
+fe r:var/r=fe:
+
+enter f:enter/f:>z1=fe#11:
+return:nofallthrough:<z_252_3=fe#12:leave:
+
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2^k:<f=fe:>h=fe:#k:asm/fe_sq(>h,<f); for (i = 1;i !lt; #k;++i) fe_sq(>h,>h);:
+
+:
+
+fe z1
+fe z2
+fe z8
+fe z9
+fe z11
+fe z22
+fe z_5_0
+fe z_10_5
+fe z_10_0
+fe z_20_10
+fe z_20_0
+fe z_40_20
+fe z_40_0
+fe z_50_10
+fe z_50_0
+fe z_100_50
+fe z_100_0
+fe z_200_100
+fe z_200_0
+fe z_250_50
+fe z_250_0
+fe z_252_2
+fe z_252_3
+
+enter pow22523
+
+z2 = z1^2^1
+z8 = z2^2^2
+z9 = z1*z8
+z11 = z2*z9
+z22 = z11^2^1
+z_5_0 = z9*z22
+z_10_5 = z_5_0^2^5
+z_10_0 = z_10_5*z_5_0
+z_20_10 = z_10_0^2^10
+z_20_0 = z_20_10*z_10_0
+z_40_20 = z_20_0^2^20
+z_40_0 = z_40_20*z_20_0
+z_50_10 = z_40_0^2^10
+z_50_0 = z_50_10*z_10_0
+z_100_50 = z_50_0^2^50
+z_100_0 = z_100_50*z_50_0
+z_200_100 = z_100_0^2^100
+z_200_0 = z_200_100*z_100_0
+z_250_50 = z_200_0^2^50
+z_250_0 = z_250_50*z_50_0
+z_252_2 = z_250_0^2^2
+z_252_3 = z_252_2*z1
+
+return
diff --git a/src/ext/ed25519/ref10/pow225521.h b/src/ext/ed25519/ref10/pow225521.h
new file mode 100644
index 0000000000..fe2af94c03
--- /dev/null
+++ b/src/ext/ed25519/ref10/pow225521.h
@@ -0,0 +1,161 @@
+/* Modified by Tor: pointless loops removed to appease analysis tools */
+
+/* qhasm: fe z1 */
+
+/* qhasm: fe z2 */
+
+/* qhasm: fe z8 */
+
+/* qhasm: fe z9 */
+
+/* qhasm: fe z11 */
+
+/* qhasm: fe z22 */
+
+/* qhasm: fe z_5_0 */
+
+/* qhasm: fe z_10_5 */
+
+/* qhasm: fe z_10_0 */
+
+/* qhasm: fe z_20_10 */
+
+/* qhasm: fe z_20_0 */
+
+/* qhasm: fe z_40_20 */
+
+/* qhasm: fe z_40_0 */
+
+/* qhasm: fe z_50_10 */
+
+/* qhasm: fe z_50_0 */
+
+/* qhasm: fe z_100_50 */
+
+/* qhasm: fe z_100_0 */
+
+/* qhasm: fe z_200_100 */
+
+/* qhasm: fe z_200_0 */
+
+/* qhasm: fe z_250_50 */
+
+/* qhasm: fe z_250_0 */
+
+/* qhasm: fe z_255_5 */
+
+/* qhasm: fe z_255_21 */
+
+/* qhasm: enter pow225521 */
+
+/* qhasm: z2 = z1^2^1 */
+/* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */
+/* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */
+fe_sq(t0,z); /* DEADCODE This loop has no effect: for (i = 1;i < 1;++i) fe_sq(t0,t0); */
+
+/* qhasm: z8 = z2^2^2 */
+/* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */
+/* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */
+fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
+
+/* qhasm: z9 = z1*z8 */
+/* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */
+/* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */
+fe_mul(t1,z,t1);
+
+/* qhasm: z11 = z2*z9 */
+/* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */
+/* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */
+fe_mul(t0,t0,t1);
+
+/* qhasm: z22 = z11^2^1 */
+/* asm 1: fe_sq(>z22=fe#3,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#3,>z22=fe#3); */
+/* asm 2: fe_sq(>z22=t2,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t2,>z22=t2); */
+fe_sq(t2,t0); /* DEADCODE This loop has no effect for (i = 1;i < 1;++i) fe_sq(t2,t2); */
+
+/* qhasm: z_5_0 = z9*z22 */
+/* asm 1: fe_mul(>z_5_0=fe#2,<z9=fe#2,<z22=fe#3); */
+/* asm 2: fe_mul(>z_5_0=t1,<z9=t1,<z22=t2); */
+fe_mul(t1,t1,t2);
+
+/* qhasm: z_10_5 = z_5_0^2^5 */
+/* asm 1: fe_sq(>z_10_5=fe#3,<z_5_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#3,>z_10_5=fe#3); */
+/* asm 2: fe_sq(>z_10_5=t2,<z_5_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t2,>z_10_5=t2); */
+fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2);
+
+/* qhasm: z_10_0 = z_10_5*z_5_0 */
+/* asm 1: fe_mul(>z_10_0=fe#2,<z_10_5=fe#3,<z_5_0=fe#2); */
+/* asm 2: fe_mul(>z_10_0=t1,<z_10_5=t2,<z_5_0=t1); */
+fe_mul(t1,t2,t1);
+
+/* qhasm: z_20_10 = z_10_0^2^10 */
+/* asm 1: fe_sq(>z_20_10=fe#3,<z_10_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#3,>z_20_10=fe#3); */
+/* asm 2: fe_sq(>z_20_10=t2,<z_10_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t2,>z_20_10=t2); */
+fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2);
+
+/* qhasm: z_20_0 = z_20_10*z_10_0 */
+/* asm 1: fe_mul(>z_20_0=fe#3,<z_20_10=fe#3,<z_10_0=fe#2); */
+/* asm 2: fe_mul(>z_20_0=t2,<z_20_10=t2,<z_10_0=t1); */
+fe_mul(t2,t2,t1);
+
+/* qhasm: z_40_20 = z_20_0^2^20 */
+/* asm 1: fe_sq(>z_40_20=fe#4,<z_20_0=fe#3); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#4,>z_40_20=fe#4); */
+/* asm 2: fe_sq(>z_40_20=t3,<z_20_0=t2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t3,>z_40_20=t3); */
+fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3);
+
+/* qhasm: z_40_0 = z_40_20*z_20_0 */
+/* asm 1: fe_mul(>z_40_0=fe#3,<z_40_20=fe#4,<z_20_0=fe#3); */
+/* asm 2: fe_mul(>z_40_0=t2,<z_40_20=t3,<z_20_0=t2); */
+fe_mul(t2,t3,t2);
+
+/* qhasm: z_50_10 = z_40_0^2^10 */
+/* asm 1: fe_sq(>z_50_10=fe#3,<z_40_0=fe#3); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#3,>z_50_10=fe#3); */
+/* asm 2: fe_sq(>z_50_10=t2,<z_40_0=t2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t2,>z_50_10=t2); */
+fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2);
+
+/* qhasm: z_50_0 = z_50_10*z_10_0 */
+/* asm 1: fe_mul(>z_50_0=fe#2,<z_50_10=fe#3,<z_10_0=fe#2); */
+/* asm 2: fe_mul(>z_50_0=t1,<z_50_10=t2,<z_10_0=t1); */
+fe_mul(t1,t2,t1);
+
+/* qhasm: z_100_50 = z_50_0^2^50 */
+/* asm 1: fe_sq(>z_100_50=fe#3,<z_50_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#3,>z_100_50=fe#3); */
+/* asm 2: fe_sq(>z_100_50=t2,<z_50_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t2,>z_100_50=t2); */
+fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2);
+
+/* qhasm: z_100_0 = z_100_50*z_50_0 */
+/* asm 1: fe_mul(>z_100_0=fe#3,<z_100_50=fe#3,<z_50_0=fe#2); */
+/* asm 2: fe_mul(>z_100_0=t2,<z_100_50=t2,<z_50_0=t1); */
+fe_mul(t2,t2,t1);
+
+/* qhasm: z_200_100 = z_100_0^2^100 */
+/* asm 1: fe_sq(>z_200_100=fe#4,<z_100_0=fe#3); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#4,>z_200_100=fe#4); */
+/* asm 2: fe_sq(>z_200_100=t3,<z_100_0=t2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t3,>z_200_100=t3); */
+fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3);
+
+/* qhasm: z_200_0 = z_200_100*z_100_0 */
+/* asm 1: fe_mul(>z_200_0=fe#3,<z_200_100=fe#4,<z_100_0=fe#3); */
+/* asm 2: fe_mul(>z_200_0=t2,<z_200_100=t3,<z_100_0=t2); */
+fe_mul(t2,t3,t2);
+
+/* qhasm: z_250_50 = z_200_0^2^50 */
+/* asm 1: fe_sq(>z_250_50=fe#3,<z_200_0=fe#3); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#3,>z_250_50=fe#3); */
+/* asm 2: fe_sq(>z_250_50=t2,<z_200_0=t2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t2,>z_250_50=t2); */
+fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2);
+
+/* qhasm: z_250_0 = z_250_50*z_50_0 */
+/* asm 1: fe_mul(>z_250_0=fe#2,<z_250_50=fe#3,<z_50_0=fe#2); */
+/* asm 2: fe_mul(>z_250_0=t1,<z_250_50=t2,<z_50_0=t1); */
+fe_mul(t1,t2,t1);
+
+/* qhasm: z_255_5 = z_250_0^2^5 */
+/* asm 1: fe_sq(>z_255_5=fe#2,<z_250_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_255_5=fe#2,>z_255_5=fe#2); */
+/* asm 2: fe_sq(>z_255_5=t1,<z_250_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_255_5=t1,>z_255_5=t1); */
+fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1);
+
+/* qhasm: z_255_21 = z_255_5*z11 */
+/* asm 1: fe_mul(>z_255_21=fe#12,<z_255_5=fe#2,<z11=fe#1); */
+/* asm 2: fe_mul(>z_255_21=out,<z_255_5=t1,<z11=t0); */
+fe_mul(out,t1,t0);
+
+/* qhasm: return */
diff --git a/src/ext/ed25519/ref10/pow225521.q b/src/ext/ed25519/ref10/pow225521.q
new file mode 100644
index 0000000000..45be57c08a
--- /dev/null
+++ b/src/ext/ed25519/ref10/pow225521.q
@@ -0,0 +1,61 @@
+:name:fe:t0:t1:t2:t3:t4:t5:t6:t7:t8:t9:z:out:
+fe r:var/r=fe:
+
+enter f:enter/f:>z1=fe#11:
+return:nofallthrough:<z_255_21=fe#12:leave:
+
+h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
+h=f^2^k:<f=fe:>h=fe:#k:asm/fe_sq(>h,<f); for (i = 1;i !lt; #k;++i) fe_sq(>h,>h);:
+
+:
+
+fe z1
+fe z2
+fe z8
+fe z9
+fe z11
+fe z22
+fe z_5_0
+fe z_10_5
+fe z_10_0
+fe z_20_10
+fe z_20_0
+fe z_40_20
+fe z_40_0
+fe z_50_10
+fe z_50_0
+fe z_100_50
+fe z_100_0
+fe z_200_100
+fe z_200_0
+fe z_250_50
+fe z_250_0
+fe z_255_5
+fe z_255_21
+
+enter pow225521
+
+z2 = z1^2^1
+z8 = z2^2^2
+z9 = z1*z8
+z11 = z2*z9
+z22 = z11^2^1
+z_5_0 = z9*z22
+z_10_5 = z_5_0^2^5
+z_10_0 = z_10_5*z_5_0
+z_20_10 = z_10_0^2^10
+z_20_0 = z_20_10*z_10_0
+z_40_20 = z_20_0^2^20
+z_40_0 = z_40_20*z_20_0
+z_50_10 = z_40_0^2^10
+z_50_0 = z_50_10*z_10_0
+z_100_50 = z_50_0^2^50
+z_100_0 = z_100_50*z_50_0
+z_200_100 = z_100_0^2^100
+z_200_0 = z_200_100*z_100_0
+z_250_50 = z_200_0^2^50
+z_250_0 = z_250_50*z_50_0
+z_255_5 = z_250_0^2^5
+z_255_21 = z_255_5*z11
+
+return
diff --git a/src/ext/ed25519/ref10/q2h.sh b/src/ext/ed25519/ref10/q2h.sh
new file mode 100755
index 0000000000..47ec5110e8
--- /dev/null
+++ b/src/ext/ed25519/ref10/q2h.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+sed 's/^#.*//' \
+| qhasm-generic \
+| sed 's_//\(.*\)$_/*\1 */_'
diff --git a/src/ext/ed25519/ref10/randombytes.h b/src/ext/ed25519/ref10/randombytes.h
new file mode 100644
index 0000000000..fc709fcefc
--- /dev/null
+++ b/src/ext/ed25519/ref10/randombytes.h
@@ -0,0 +1,4 @@
+/* Added for Tor. */
+#include "crypto.h"
+#define randombytes(b, n) \
+ (crypto_strongest_rand((b), (n)))
diff --git a/src/ext/ed25519/ref10/sc.h b/src/ext/ed25519/ref10/sc.h
new file mode 100644
index 0000000000..d32ed2e8ca
--- /dev/null
+++ b/src/ext/ed25519/ref10/sc.h
@@ -0,0 +1,15 @@
+#ifndef SC_H
+#define SC_H
+
+/*
+The set of scalars is \Z/l
+where l = 2^252 + 27742317777372353535851937790883648493.
+*/
+
+#define sc_reduce crypto_sign_ed25519_ref10_sc_reduce
+#define sc_muladd crypto_sign_ed25519_ref10_sc_muladd
+
+extern void sc_reduce(unsigned char *);
+extern void sc_muladd(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
+
+#endif
diff --git a/src/ext/ed25519/ref10/sc_muladd.c b/src/ext/ed25519/ref10/sc_muladd.c
new file mode 100644
index 0000000000..20b94c1049
--- /dev/null
+++ b/src/ext/ed25519/ref10/sc_muladd.c
@@ -0,0 +1,368 @@
+#include "sc.h"
+#include "crypto_int64.h"
+#include "crypto_uint32.h"
+#include "crypto_uint64.h"
+
+static crypto_uint64 load_3(const unsigned char *in)
+{
+ crypto_uint64 result;
+ result = (crypto_uint64) in[0];
+ result |= ((crypto_uint64) in[1]) << 8;
+ result |= ((crypto_uint64) in[2]) << 16;
+ return result;
+}
+
+static crypto_uint64 load_4(const unsigned char *in)
+{
+ crypto_uint64 result;
+ result = (crypto_uint64) in[0];
+ result |= ((crypto_uint64) in[1]) << 8;
+ result |= ((crypto_uint64) in[2]) << 16;
+ result |= ((crypto_uint64) in[3]) << 24;
+ return result;
+}
+
+/*
+Input:
+ a[0]+256*a[1]+...+256^31*a[31] = a
+ b[0]+256*b[1]+...+256^31*b[31] = b
+ c[0]+256*c[1]+...+256^31*c[31] = c
+
+Output:
+ s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+*/
+
+void sc_muladd(unsigned char *s,const unsigned char *a,const unsigned char *b,const unsigned char *c)
+{
+ crypto_int64 a0 = 2097151 & load_3(a);
+ crypto_int64 a1 = 2097151 & (load_4(a + 2) >> 5);
+ crypto_int64 a2 = 2097151 & (load_3(a + 5) >> 2);
+ crypto_int64 a3 = 2097151 & (load_4(a + 7) >> 7);
+ crypto_int64 a4 = 2097151 & (load_4(a + 10) >> 4);
+ crypto_int64 a5 = 2097151 & (load_3(a + 13) >> 1);
+ crypto_int64 a6 = 2097151 & (load_4(a + 15) >> 6);
+ crypto_int64 a7 = 2097151 & (load_3(a + 18) >> 3);
+ crypto_int64 a8 = 2097151 & load_3(a + 21);
+ crypto_int64 a9 = 2097151 & (load_4(a + 23) >> 5);
+ crypto_int64 a10 = 2097151 & (load_3(a + 26) >> 2);
+ crypto_int64 a11 = (load_4(a + 28) >> 7);
+ crypto_int64 b0 = 2097151 & load_3(b);
+ crypto_int64 b1 = 2097151 & (load_4(b + 2) >> 5);
+ crypto_int64 b2 = 2097151 & (load_3(b + 5) >> 2);
+ crypto_int64 b3 = 2097151 & (load_4(b + 7) >> 7);
+ crypto_int64 b4 = 2097151 & (load_4(b + 10) >> 4);
+ crypto_int64 b5 = 2097151 & (load_3(b + 13) >> 1);
+ crypto_int64 b6 = 2097151 & (load_4(b + 15) >> 6);
+ crypto_int64 b7 = 2097151 & (load_3(b + 18) >> 3);
+ crypto_int64 b8 = 2097151 & load_3(b + 21);
+ crypto_int64 b9 = 2097151 & (load_4(b + 23) >> 5);
+ crypto_int64 b10 = 2097151 & (load_3(b + 26) >> 2);
+ crypto_int64 b11 = (load_4(b + 28) >> 7);
+ crypto_int64 c0 = 2097151 & load_3(c);
+ crypto_int64 c1 = 2097151 & (load_4(c + 2) >> 5);
+ crypto_int64 c2 = 2097151 & (load_3(c + 5) >> 2);
+ crypto_int64 c3 = 2097151 & (load_4(c + 7) >> 7);
+ crypto_int64 c4 = 2097151 & (load_4(c + 10) >> 4);
+ crypto_int64 c5 = 2097151 & (load_3(c + 13) >> 1);
+ crypto_int64 c6 = 2097151 & (load_4(c + 15) >> 6);
+ crypto_int64 c7 = 2097151 & (load_3(c + 18) >> 3);
+ crypto_int64 c8 = 2097151 & load_3(c + 21);
+ crypto_int64 c9 = 2097151 & (load_4(c + 23) >> 5);
+ crypto_int64 c10 = 2097151 & (load_3(c + 26) >> 2);
+ crypto_int64 c11 = (load_4(c + 28) >> 7);
+ crypto_int64 s0;
+ crypto_int64 s1;
+ crypto_int64 s2;
+ crypto_int64 s3;
+ crypto_int64 s4;
+ crypto_int64 s5;
+ crypto_int64 s6;
+ crypto_int64 s7;
+ crypto_int64 s8;
+ crypto_int64 s9;
+ crypto_int64 s10;
+ crypto_int64 s11;
+ crypto_int64 s12;
+ crypto_int64 s13;
+ crypto_int64 s14;
+ crypto_int64 s15;
+ crypto_int64 s16;
+ crypto_int64 s17;
+ crypto_int64 s18;
+ crypto_int64 s19;
+ crypto_int64 s20;
+ crypto_int64 s21;
+ crypto_int64 s22;
+ crypto_int64 s23;
+ crypto_int64 carry0;
+ crypto_int64 carry1;
+ crypto_int64 carry2;
+ crypto_int64 carry3;
+ crypto_int64 carry4;
+ crypto_int64 carry5;
+ crypto_int64 carry6;
+ crypto_int64 carry7;
+ crypto_int64 carry8;
+ crypto_int64 carry9;
+ crypto_int64 carry10;
+ crypto_int64 carry11;
+ crypto_int64 carry12;
+ crypto_int64 carry13;
+ crypto_int64 carry14;
+ crypto_int64 carry15;
+ crypto_int64 carry16;
+ crypto_int64 carry17;
+ crypto_int64 carry18;
+ crypto_int64 carry19;
+ crypto_int64 carry20;
+ crypto_int64 carry21;
+ crypto_int64 carry22;
+
+ s0 = c0 + a0*b0;
+ s1 = c1 + a0*b1 + a1*b0;
+ s2 = c2 + a0*b2 + a1*b1 + a2*b0;
+ s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0;
+ s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0;
+ s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0;
+ s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0;
+ s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0;
+ s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0;
+ s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0;
+ s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0;
+ s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0;
+ s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1;
+ s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2;
+ s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3;
+ s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4;
+ s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5;
+ s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6;
+ s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7;
+ s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8;
+ s20 = a9*b11 + a10*b10 + a11*b9;
+ s21 = a10*b11 + a11*b10;
+ s22 = a11*b11;
+ s23 = 0;
+
+ carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+ carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= SHL64(carry12,21);
+ carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= SHL64(carry14,21);
+ carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= SHL64(carry16,21);
+ carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= SHL64(carry18,21);
+ carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= SHL64(carry20,21);
+ carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= SHL64(carry22,21);
+
+ carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+ carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= SHL64(carry13,21);
+ carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= SHL64(carry15,21);
+ carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= SHL64(carry17,21);
+ carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= SHL64(carry19,21);
+ carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= SHL64(carry21,21);
+
+ s11 += s23 * 666643;
+ s12 += s23 * 470296;
+ s13 += s23 * 654183;
+ s14 -= s23 * 997805;
+ s15 += s23 * 136657;
+ s16 -= s23 * 683901;
+ s23 = 0;
+
+ s10 += s22 * 666643;
+ s11 += s22 * 470296;
+ s12 += s22 * 654183;
+ s13 -= s22 * 997805;
+ s14 += s22 * 136657;
+ s15 -= s22 * 683901;
+ s22 = 0;
+
+ s9 += s21 * 666643;
+ s10 += s21 * 470296;
+ s11 += s21 * 654183;
+ s12 -= s21 * 997805;
+ s13 += s21 * 136657;
+ s14 -= s21 * 683901;
+ s21 = 0;
+
+ s8 += s20 * 666643;
+ s9 += s20 * 470296;
+ s10 += s20 * 654183;
+ s11 -= s20 * 997805;
+ s12 += s20 * 136657;
+ s13 -= s20 * 683901;
+ s20 = 0;
+
+ s7 += s19 * 666643;
+ s8 += s19 * 470296;
+ s9 += s19 * 654183;
+ s10 -= s19 * 997805;
+ s11 += s19 * 136657;
+ s12 -= s19 * 683901;
+ s19 = 0;
+
+ s6 += s18 * 666643;
+ s7 += s18 * 470296;
+ s8 += s18 * 654183;
+ s9 -= s18 * 997805;
+ s10 += s18 * 136657;
+ s11 -= s18 * 683901;
+ s18 = 0;
+
+ carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+ carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= SHL64(carry12,21);
+ carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= SHL64(carry14,21);
+ carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= SHL64(carry16,21);
+
+ carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+ carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= SHL64(carry13,21);
+ carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= SHL64(carry15,21);
+
+ s5 += s17 * 666643;
+ s6 += s17 * 470296;
+ s7 += s17 * 654183;
+ s8 -= s17 * 997805;
+ s9 += s17 * 136657;
+ s10 -= s17 * 683901;
+ s17 = 0;
+
+ s4 += s16 * 666643;
+ s5 += s16 * 470296;
+ s6 += s16 * 654183;
+ s7 -= s16 * 997805;
+ s8 += s16 * 136657;
+ s9 -= s16 * 683901;
+ s16 = 0;
+
+ s3 += s15 * 666643;
+ s4 += s15 * 470296;
+ s5 += s15 * 654183;
+ s6 -= s15 * 997805;
+ s7 += s15 * 136657;
+ s8 -= s15 * 683901;
+ s15 = 0;
+
+ s2 += s14 * 666643;
+ s3 += s14 * 470296;
+ s4 += s14 * 654183;
+ s5 -= s14 * 997805;
+ s6 += s14 * 136657;
+ s7 -= s14 * 683901;
+ s14 = 0;
+
+ s1 += s13 * 666643;
+ s2 += s13 * 470296;
+ s3 += s13 * 654183;
+ s4 -= s13 * 997805;
+ s5 += s13 * 136657;
+ s6 -= s13 * 683901;
+ s13 = 0;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+
+ carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry1 = s1 >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry2 = s2 >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry3 = s3 >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry4 = s4 >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry5 = s5 >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry6 = s6 >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry7 = s7 >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry8 = s8 >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry9 = s9 >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry10 = s10 >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+ carry11 = s11 >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry1 = s1 >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry2 = s2 >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry3 = s3 >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry4 = s4 >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry5 = s5 >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry6 = s6 >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry7 = s7 >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry8 = s8 >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry9 = s9 >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry10 = s10 >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+
+ s[0] = s0 >> 0;
+ s[1] = s0 >> 8;
+ s[2] = (s0 >> 16) | SHL64(s1,5);
+ s[3] = s1 >> 3;
+ s[4] = s1 >> 11;
+ s[5] = (s1 >> 19) | SHL64(s2,2);
+ s[6] = s2 >> 6;
+ s[7] = (s2 >> 14) | SHL64(s3,7);
+ s[8] = s3 >> 1;
+ s[9] = s3 >> 9;
+ s[10] = (s3 >> 17) | SHL64(s4,4);
+ s[11] = s4 >> 4;
+ s[12] = s4 >> 12;
+ s[13] = (s4 >> 20) | SHL64(s5,1);
+ s[14] = s5 >> 7;
+ s[15] = (s5 >> 15) | SHL64(s6,6);
+ s[16] = s6 >> 2;
+ s[17] = s6 >> 10;
+ s[18] = (s6 >> 18) | SHL64(s7,3);
+ s[19] = s7 >> 5;
+ s[20] = s7 >> 13;
+ s[21] = s8 >> 0;
+ s[22] = s8 >> 8;
+ s[23] = (s8 >> 16) | SHL64(s9,5);
+ s[24] = s9 >> 3;
+ s[25] = s9 >> 11;
+ s[26] = (s9 >> 19) | SHL64(s10,2);
+ s[27] = s10 >> 6;
+ s[28] = (s10 >> 14) | SHL64(s11,7);
+ s[29] = s11 >> 1;
+ s[30] = s11 >> 9;
+ s[31] = s11 >> 17;
+}
diff --git a/src/ext/ed25519/ref10/sc_reduce.c b/src/ext/ed25519/ref10/sc_reduce.c
new file mode 100644
index 0000000000..c5afa53741
--- /dev/null
+++ b/src/ext/ed25519/ref10/sc_reduce.c
@@ -0,0 +1,275 @@
+#include "sc.h"
+#include "crypto_int64.h"
+#include "crypto_uint32.h"
+#include "crypto_uint64.h"
+
+static crypto_uint64 load_3(const unsigned char *in)
+{
+ crypto_uint64 result;
+ result = (crypto_uint64) in[0];
+ result |= ((crypto_uint64) in[1]) << 8;
+ result |= ((crypto_uint64) in[2]) << 16;
+ return result;
+}
+
+static crypto_uint64 load_4(const unsigned char *in)
+{
+ crypto_uint64 result;
+ result = (crypto_uint64) in[0];
+ result |= ((crypto_uint64) in[1]) << 8;
+ result |= ((crypto_uint64) in[2]) << 16;
+ result |= ((crypto_uint64) in[3]) << 24;
+ return result;
+}
+
+/*
+Input:
+ s[0]+256*s[1]+...+256^63*s[63] = s
+
+Output:
+ s[0]+256*s[1]+...+256^31*s[31] = s mod l
+ where l = 2^252 + 27742317777372353535851937790883648493.
+ Overwrites s in place.
+*/
+
+void sc_reduce(unsigned char *s)
+{
+ crypto_int64 s0 = 2097151 & load_3(s);
+ crypto_int64 s1 = 2097151 & (load_4(s + 2) >> 5);
+ crypto_int64 s2 = 2097151 & (load_3(s + 5) >> 2);
+ crypto_int64 s3 = 2097151 & (load_4(s + 7) >> 7);
+ crypto_int64 s4 = 2097151 & (load_4(s + 10) >> 4);
+ crypto_int64 s5 = 2097151 & (load_3(s + 13) >> 1);
+ crypto_int64 s6 = 2097151 & (load_4(s + 15) >> 6);
+ crypto_int64 s7 = 2097151 & (load_3(s + 18) >> 3);
+ crypto_int64 s8 = 2097151 & load_3(s + 21);
+ crypto_int64 s9 = 2097151 & (load_4(s + 23) >> 5);
+ crypto_int64 s10 = 2097151 & (load_3(s + 26) >> 2);
+ crypto_int64 s11 = 2097151 & (load_4(s + 28) >> 7);
+ crypto_int64 s12 = 2097151 & (load_4(s + 31) >> 4);
+ crypto_int64 s13 = 2097151 & (load_3(s + 34) >> 1);
+ crypto_int64 s14 = 2097151 & (load_4(s + 36) >> 6);
+ crypto_int64 s15 = 2097151 & (load_3(s + 39) >> 3);
+ crypto_int64 s16 = 2097151 & load_3(s + 42);
+ crypto_int64 s17 = 2097151 & (load_4(s + 44) >> 5);
+ crypto_int64 s18 = 2097151 & (load_3(s + 47) >> 2);
+ crypto_int64 s19 = 2097151 & (load_4(s + 49) >> 7);
+ crypto_int64 s20 = 2097151 & (load_4(s + 52) >> 4);
+ crypto_int64 s21 = 2097151 & (load_3(s + 55) >> 1);
+ crypto_int64 s22 = 2097151 & (load_4(s + 57) >> 6);
+ crypto_int64 s23 = (load_4(s + 60) >> 3);
+ crypto_int64 carry0;
+ crypto_int64 carry1;
+ crypto_int64 carry2;
+ crypto_int64 carry3;
+ crypto_int64 carry4;
+ crypto_int64 carry5;
+ crypto_int64 carry6;
+ crypto_int64 carry7;
+ crypto_int64 carry8;
+ crypto_int64 carry9;
+ crypto_int64 carry10;
+ crypto_int64 carry11;
+ crypto_int64 carry12;
+ crypto_int64 carry13;
+ crypto_int64 carry14;
+ crypto_int64 carry15;
+ crypto_int64 carry16;
+
+ s11 += s23 * 666643;
+ s12 += s23 * 470296;
+ s13 += s23 * 654183;
+ s14 -= s23 * 997805;
+ s15 += s23 * 136657;
+ s16 -= s23 * 683901;
+ s23 = 0;
+
+ s10 += s22 * 666643;
+ s11 += s22 * 470296;
+ s12 += s22 * 654183;
+ s13 -= s22 * 997805;
+ s14 += s22 * 136657;
+ s15 -= s22 * 683901;
+ s22 = 0;
+
+ s9 += s21 * 666643;
+ s10 += s21 * 470296;
+ s11 += s21 * 654183;
+ s12 -= s21 * 997805;
+ s13 += s21 * 136657;
+ s14 -= s21 * 683901;
+ s21 = 0;
+
+ s8 += s20 * 666643;
+ s9 += s20 * 470296;
+ s10 += s20 * 654183;
+ s11 -= s20 * 997805;
+ s12 += s20 * 136657;
+ s13 -= s20 * 683901;
+ s20 = 0;
+
+ s7 += s19 * 666643;
+ s8 += s19 * 470296;
+ s9 += s19 * 654183;
+ s10 -= s19 * 997805;
+ s11 += s19 * 136657;
+ s12 -= s19 * 683901;
+ s19 = 0;
+
+ s6 += s18 * 666643;
+ s7 += s18 * 470296;
+ s8 += s18 * 654183;
+ s9 -= s18 * 997805;
+ s10 += s18 * 136657;
+ s11 -= s18 * 683901;
+ s18 = 0;
+
+ carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+ carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= SHL64(carry12,21);
+ carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= SHL64(carry14,21);
+ carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= SHL64(carry16,21);
+
+ carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+ carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= SHL64(carry13,21);
+ carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= SHL64(carry15,21);
+
+ s5 += s17 * 666643;
+ s6 += s17 * 470296;
+ s7 += s17 * 654183;
+ s8 -= s17 * 997805;
+ s9 += s17 * 136657;
+ s10 -= s17 * 683901;
+ s17 = 0;
+
+ s4 += s16 * 666643;
+ s5 += s16 * 470296;
+ s6 += s16 * 654183;
+ s7 -= s16 * 997805;
+ s8 += s16 * 136657;
+ s9 -= s16 * 683901;
+ s16 = 0;
+
+ s3 += s15 * 666643;
+ s4 += s15 * 470296;
+ s5 += s15 * 654183;
+ s6 -= s15 * 997805;
+ s7 += s15 * 136657;
+ s8 -= s15 * 683901;
+ s15 = 0;
+
+ s2 += s14 * 666643;
+ s3 += s14 * 470296;
+ s4 += s14 * 654183;
+ s5 -= s14 * 997805;
+ s6 += s14 * 136657;
+ s7 -= s14 * 683901;
+ s14 = 0;
+
+ s1 += s13 * 666643;
+ s2 += s13 * 470296;
+ s3 += s13 * 654183;
+ s4 -= s13 * 997805;
+ s5 += s13 * 136657;
+ s6 -= s13 * 683901;
+ s13 = 0;
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+
+ carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry1 = s1 >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry2 = s2 >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry3 = s3 >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry4 = s4 >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry5 = s5 >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry6 = s6 >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry7 = s7 >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry8 = s8 >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry9 = s9 >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry10 = s10 >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+ carry11 = s11 >> 21; s12 += carry11; s11 -= SHL64(carry11,21);
+
+ s0 += s12 * 666643;
+ s1 += s12 * 470296;
+ s2 += s12 * 654183;
+ s3 -= s12 * 997805;
+ s4 += s12 * 136657;
+ s5 -= s12 * 683901;
+ s12 = 0;
+
+ carry0 = s0 >> 21; s1 += carry0; s0 -= SHL64(carry0,21);
+ carry1 = s1 >> 21; s2 += carry1; s1 -= SHL64(carry1,21);
+ carry2 = s2 >> 21; s3 += carry2; s2 -= SHL64(carry2,21);
+ carry3 = s3 >> 21; s4 += carry3; s3 -= SHL64(carry3,21);
+ carry4 = s4 >> 21; s5 += carry4; s4 -= SHL64(carry4,21);
+ carry5 = s5 >> 21; s6 += carry5; s5 -= SHL64(carry5,21);
+ carry6 = s6 >> 21; s7 += carry6; s6 -= SHL64(carry6,21);
+ carry7 = s7 >> 21; s8 += carry7; s7 -= SHL64(carry7,21);
+ carry8 = s8 >> 21; s9 += carry8; s8 -= SHL64(carry8,21);
+ carry9 = s9 >> 21; s10 += carry9; s9 -= SHL64(carry9,21);
+ carry10 = s10 >> 21; s11 += carry10; s10 -= SHL64(carry10,21);
+
+ s[0] = s0 >> 0;
+ s[1] = s0 >> 8;
+ s[2] = (s0 >> 16) | SHL64(s1,5);
+ s[3] = s1 >> 3;
+ s[4] = s1 >> 11;
+ s[5] = (s1 >> 19) | SHL64(s2,2);
+ s[6] = s2 >> 6;
+ s[7] = (s2 >> 14) | SHL64(s3,7);
+ s[8] = s3 >> 1;
+ s[9] = s3 >> 9;
+ s[10] = (s3 >> 17) | SHL64(s4,4);
+ s[11] = s4 >> 4;
+ s[12] = s4 >> 12;
+ s[13] = (s4 >> 20) | SHL64(s5,1);
+ s[14] = s5 >> 7;
+ s[15] = (s5 >> 15) | SHL64(s6,6);
+ s[16] = s6 >> 2;
+ s[17] = s6 >> 10;
+ s[18] = (s6 >> 18) | SHL64(s7,3);
+ s[19] = s7 >> 5;
+ s[20] = s7 >> 13;
+ s[21] = s8 >> 0;
+ s[22] = s8 >> 8;
+ s[23] = (s8 >> 16) | SHL64(s9,5);
+ s[24] = s9 >> 3;
+ s[25] = s9 >> 11;
+ s[26] = (s9 >> 19) | SHL64(s10,2);
+ s[27] = s10 >> 6;
+ s[28] = (s10 >> 14) | SHL64(s11,7);
+ s[29] = s11 >> 1;
+ s[30] = s11 >> 9;
+ s[31] = s11 >> 17;
+}
diff --git a/src/ext/ed25519/ref10/sign.c b/src/ext/ed25519/ref10/sign.c
new file mode 100644
index 0000000000..1190a0fc99
--- /dev/null
+++ b/src/ext/ed25519/ref10/sign.c
@@ -0,0 +1,29 @@
+/* (Modified by Tor to generate detached signatures.) */
+#include <string.h>
+#include "crypto_sign.h"
+#include "crypto_hash_sha512.h"
+#include "ge.h"
+#include "sc.h"
+
+int crypto_sign(
+ unsigned char *sig,
+ const unsigned char *m, size_t mlen,
+ const unsigned char *sk,const unsigned char *pk
+)
+{
+ unsigned char nonce[64];
+ unsigned char hram[64];
+ ge_p3 R;
+
+ crypto_hash_sha512_2(nonce, sk+32, 32, m, mlen);
+
+ sc_reduce(nonce);
+ ge_scalarmult_base(&R,nonce);
+ ge_p3_tobytes(sig,&R);
+
+ crypto_hash_sha512_3(hram, sig, 32, pk, 32, m, mlen);
+ sc_reduce(hram);
+ sc_muladd(sig + 32,hram,sk,nonce);
+
+ return 0;
+}
diff --git a/src/ext/ed25519/ref10/sqrtm1.h b/src/ext/ed25519/ref10/sqrtm1.h
new file mode 100644
index 0000000000..d8caa23b6a
--- /dev/null
+++ b/src/ext/ed25519/ref10/sqrtm1.h
@@ -0,0 +1 @@
+-32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482
diff --git a/src/ext/ed25519/ref10/sqrtm1.py b/src/ext/ed25519/ref10/sqrtm1.py
new file mode 100644
index 0000000000..9a47fbc12a
--- /dev/null
+++ b/src/ext/ed25519/ref10/sqrtm1.py
@@ -0,0 +1,28 @@
+q = 2**255 - 19
+
+def expmod(b,e,m):
+ if e == 0: return 1
+ t = expmod(b,e/2,m)**2 % m
+ if e & 1: t = (t*b) % m
+ return t
+
+def inv(x):
+ return expmod(x,q-2,q)
+
+def radix255(x):
+ x = x % q
+ if x + x > q: x -= q
+ x = [x,0,0,0,0,0,0,0,0,0]
+ bits = [26,25,26,25,26,25,26,25,26,25]
+ for i in range(9):
+ carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
+ x[i] -= carry * 2**bits[i]
+ x[i + 1] += carry
+ result = ""
+ for i in range(9):
+ result = result+str(x[i])+","
+ result = result+str(x[9])
+ return result
+
+I = expmod(2,(q-1)/4,q)
+print radix255(I)
diff --git a/src/ext/ht.h b/src/ext/ht.h
index 838710784f..61e9719224 100644
--- a/src/ext/ht.h
+++ b/src/ext/ht.h
@@ -302,8 +302,8 @@ ht_string_hash(const char *s)
} \
}
-#define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn, \
- reallocfn, freefn) \
+#define HT_GENERATE2(name, type, field, hashfn, eqfn, load, reallocarrayfn, \
+ freefn) \
/* Primes that aren't too far from powers of two. We stop at */ \
/* P=402653189 because P*sizeof(void*) is less than SSIZE_MAX */ \
/* even on a 32-bit platform. */ \
@@ -336,7 +336,7 @@ ht_string_hash(const char *s)
new_load_limit = (unsigned)(load*new_len); \
} while (new_load_limit <= size && \
prime_idx < (int)name##_N_PRIMES); \
- if ((new_table = mallocfn(new_len*sizeof(struct type*)))) { \
+ if ((new_table = reallocarrayfn(NULL, new_len, sizeof(struct type*)))) { \
unsigned b; \
memset(new_table, 0, new_len*sizeof(struct type*)); \
for (b = 0; b < head->hth_table_length; ++b) { \
@@ -356,7 +356,7 @@ ht_string_hash(const char *s)
head->hth_table = new_table; \
} else { \
unsigned b, b2; \
- new_table = reallocfn(head->hth_table, new_len*sizeof(struct type*)); \
+ new_table = reallocarrayfn(head->hth_table, new_len, sizeof(struct type*)); \
if (!new_table) return -1; \
memset(new_table + head->hth_table_length, 0, \
(new_len - head->hth_table_length)*sizeof(struct type*)); \
@@ -427,6 +427,21 @@ ht_string_hash(const char *s)
return 0; \
}
+#define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn, \
+ reallocfn, freefn) \
+ static void * \
+ name##_reallocarray(void *arg, size_t a, size_t b) \
+ { \
+ if ((b) && (a) > SIZE_MAX / (b)) \
+ return NULL; \
+ if (arg) \
+ return reallocfn((arg),(a)*(b)); \
+ else \
+ return mallocfn((a)*(b)); \
+ } \
+ HT_GENERATE2(name, type, field, hashfn, eqfn, load, \
+ name##_reallocarray, freefn)
+
/** Implements an over-optimized "find and insert if absent" block;
* not meant for direct usage by typical code, or usage outside the critical
* path.*/
diff --git a/src/ext/include.am b/src/ext/include.am
index 26e194e88e..576fd4efb8 100644
--- a/src/ext/include.am
+++ b/src/ext/include.am
@@ -15,4 +15,80 @@ EXTHEADERS = \
noinst_HEADERS+= $(EXTHEADERS)
+src_ext_ed25519_ref10_libed25519_ref10_a_CFLAGS=
+
+src_ext_ed25519_ref10_libed25519_ref10_a_SOURCES= \
+ src/ext/ed25519/ref10/fe_0.c \
+ src/ext/ed25519/ref10/fe_1.c \
+ src/ext/ed25519/ref10/fe_add.c \
+ src/ext/ed25519/ref10/fe_cmov.c \
+ src/ext/ed25519/ref10/fe_copy.c \
+ src/ext/ed25519/ref10/fe_frombytes.c \
+ src/ext/ed25519/ref10/fe_invert.c \
+ src/ext/ed25519/ref10/fe_isnegative.c \
+ src/ext/ed25519/ref10/fe_isnonzero.c \
+ src/ext/ed25519/ref10/fe_mul.c \
+ src/ext/ed25519/ref10/fe_neg.c \
+ src/ext/ed25519/ref10/fe_pow22523.c \
+ src/ext/ed25519/ref10/fe_sq.c \
+ src/ext/ed25519/ref10/fe_sq2.c \
+ src/ext/ed25519/ref10/fe_sub.c \
+ src/ext/ed25519/ref10/fe_tobytes.c \
+ src/ext/ed25519/ref10/ge_add.c \
+ src/ext/ed25519/ref10/ge_double_scalarmult.c \
+ src/ext/ed25519/ref10/ge_frombytes.c \
+ src/ext/ed25519/ref10/ge_madd.c \
+ src/ext/ed25519/ref10/ge_msub.c \
+ src/ext/ed25519/ref10/ge_p1p1_to_p2.c \
+ src/ext/ed25519/ref10/ge_p1p1_to_p3.c \
+ src/ext/ed25519/ref10/ge_p2_0.c \
+ src/ext/ed25519/ref10/ge_p2_dbl.c \
+ src/ext/ed25519/ref10/ge_p3_0.c \
+ src/ext/ed25519/ref10/ge_p3_dbl.c \
+ src/ext/ed25519/ref10/ge_p3_to_cached.c \
+ src/ext/ed25519/ref10/ge_p3_to_p2.c \
+ src/ext/ed25519/ref10/ge_p3_tobytes.c \
+ src/ext/ed25519/ref10/ge_precomp_0.c \
+ src/ext/ed25519/ref10/ge_scalarmult_base.c \
+ src/ext/ed25519/ref10/ge_sub.c \
+ src/ext/ed25519/ref10/ge_tobytes.c \
+ src/ext/ed25519/ref10/keypair.c \
+ src/ext/ed25519/ref10/open.c \
+ src/ext/ed25519/ref10/sc_muladd.c \
+ src/ext/ed25519/ref10/sc_reduce.c \
+ src/ext/ed25519/ref10/sign.c \
+ src/ext/ed25519/ref10/keyconv.c \
+ src/ext/ed25519/ref10/blinding.c
+
+ED25519_REF10_HDRS = \
+ src/ext/ed25519/ref10/api.h \
+ src/ext/ed25519/ref10/base.h \
+ src/ext/ed25519/ref10/base2.h \
+ src/ext/ed25519/ref10/crypto_hash_sha512.h \
+ src/ext/ed25519/ref10/crypto_int32.h \
+ src/ext/ed25519/ref10/crypto_int64.h \
+ src/ext/ed25519/ref10/crypto_sign.h \
+ src/ext/ed25519/ref10/crypto_uint32.h \
+ src/ext/ed25519/ref10/crypto_uint64.h \
+ src/ext/ed25519/ref10/crypto_verify_32.h \
+ src/ext/ed25519/ref10/d.h \
+ src/ext/ed25519/ref10/d2.h \
+ src/ext/ed25519/ref10/ed25519_ref10.h \
+ src/ext/ed25519/ref10/fe.h \
+ src/ext/ed25519/ref10/ge.h \
+ src/ext/ed25519/ref10/ge_add.h \
+ src/ext/ed25519/ref10/ge_madd.h \
+ src/ext/ed25519/ref10/ge_msub.h \
+ src/ext/ed25519/ref10/ge_p2_dbl.h \
+ src/ext/ed25519/ref10/ge_sub.h \
+ src/ext/ed25519/ref10/pow22523.h \
+ src/ext/ed25519/ref10/pow225521.h \
+ src/ext/ed25519/ref10/randombytes.h \
+ src/ext/ed25519/ref10/sc.h \
+ src/ext/ed25519/ref10/sqrtm1.h
+
+noinst_HEADERS += $(ED25519_REF10_HDRS)
+
+LIBED25519_REF10=src/ext/ed25519/ref10/libed25519_ref10.a
+noinst_LIBRARIES += $(LIBED25519_REF10)
diff --git a/src/ext/trunnel/trunnel-impl.h b/src/ext/trunnel/trunnel-impl.h
new file mode 100644
index 0000000000..c88ee3988e
--- /dev/null
+++ b/src/ext/trunnel/trunnel-impl.h
@@ -0,0 +1,310 @@
+/* trunnel-impl.h -- copied from Trunnel v1.2
+ * https://gitweb.torproject.org/trunnel.git
+ * You probably shouldn't edit this file.
+ */
+/* trunnel-impl.h -- Implementation helpers for trunnel, included by
+ * generated trunnel files
+ *
+ * Copyright 2014, The Tor Project, Inc.
+ * See license at the end of this file for copying information.
+ */
+
+#ifndef TRUNNEL_IMPL_H_INCLUDED_
+#define TRUNNEL_IMPL_H_INCLUDED_
+#include "trunnel.h"
+#include <assert.h>
+#include <string.h>
+#ifdef TRUNNEL_LOCAL_H
+#include "trunnel-local.h"
+#endif
+
+#ifdef _MSC_VER
+#define uint8_t unsigned char
+#define uint16_t unsigned short
+#define uint32_t unsigned int
+#define uint64_t unsigned __int64
+#define inline __inline
+#else
+#include <stdint.h>
+#endif
+
+#ifdef _WIN32
+uint32_t trunnel_htonl(uint32_t a);
+uint32_t trunnel_ntohl(uint32_t a);
+uint16_t trunnel_htons(uint16_t a);
+uint16_t trunnel_ntohs(uint16_t a);
+#else
+#include <arpa/inet.h>
+#define trunnel_htonl(x) htonl(x)
+#define trunnel_htons(x) htons(x)
+#define trunnel_ntohl(x) ntohl(x)
+#define trunnel_ntohs(x) ntohs(x)
+#endif
+uint64_t trunnel_htonll(uint64_t a);
+uint64_t trunnel_ntohll(uint64_t a);
+
+#ifndef trunnel_assert
+#define trunnel_assert(x) assert(x)
+#endif
+
+static inline void
+trunnel_set_uint64(void *p, uint64_t v) {
+ memcpy(p, &v, 8);
+}
+static inline void
+trunnel_set_uint32(void *p, uint32_t v) {
+ memcpy(p, &v, 4);
+}
+static inline void
+trunnel_set_uint16(void *p, uint16_t v) {
+ memcpy(p, &v, 2);
+}
+static inline void
+trunnel_set_uint8(void *p, uint8_t v) {
+ memcpy(p, &v, 1);
+}
+
+static inline uint64_t
+trunnel_get_uint64(const void *p) {
+ uint64_t x;
+ memcpy(&x, p, 8);
+ return x;
+}
+static inline uint32_t
+trunnel_get_uint32(const void *p) {
+ uint32_t x;
+ memcpy(&x, p, 4);
+ return x;
+}
+static inline uint16_t
+trunnel_get_uint16(const void *p) {
+ uint16_t x;
+ memcpy(&x, p, 2);
+ return x;
+}
+static inline uint8_t
+trunnel_get_uint8(const void *p) {
+ return *(const uint8_t*)p;
+}
+
+
+#ifdef TRUNNEL_DEBUG_FAILING_ALLOC
+extern int trunnel_provoke_alloc_failure;
+
+static inline void *
+trunnel_malloc(size_t n)
+{
+ if (trunnel_provoke_alloc_failure) {
+ if (--trunnel_provoke_alloc_failure == 0)
+ return NULL;
+ }
+ return malloc(n);
+}
+static inline void *
+trunnel_calloc(size_t a, size_t b)
+{
+ if (trunnel_provoke_alloc_failure) {
+ if (--trunnel_provoke_alloc_failure == 0)
+ return NULL;
+ }
+ return calloc(a,b);
+}
+static inline char *
+trunnel_strdup(const char *s)
+{
+ if (trunnel_provoke_alloc_failure) {
+ if (--trunnel_provoke_alloc_failure == 0)
+ return NULL;
+ }
+ return strdup(s);
+}
+#else
+#ifndef trunnel_malloc
+#define trunnel_malloc(x) (malloc((x)))
+#endif
+#ifndef trunnel_calloc
+#define trunnel_calloc(a,b) (calloc((a),(b)))
+#endif
+#ifndef trunnel_strdup
+#define trunnel_strdup(s) (strdup((s)))
+#endif
+#endif
+
+#ifndef trunnel_realloc
+#define trunnel_realloc(a,b) realloc((a),(b))
+#endif
+
+#ifndef trunnel_free_
+#define trunnel_free_(x) (free(x))
+#endif
+#define trunnel_free(x) ((x) ? (trunnel_free_(x),0) : (0))
+
+#ifndef trunnel_abort
+#define trunnel_abort() abort()
+#endif
+
+#ifndef trunnel_memwipe
+#define trunnel_memwipe(mem, len) ((void)0)
+#define trunnel_wipestr(s) ((void)0)
+#else
+#define trunnel_wipestr(s) do { \
+ if (s) \
+ trunnel_memwipe(s, strlen(s)); \
+ } while (0)
+#endif
+
+/* ====== dynamic arrays ======== */
+
+#ifdef NDEBUG
+#define TRUNNEL_DYNARRAY_GET(da, n) \
+ ((da)->elts_[(n)])
+#else
+/** Return the 'n'th element of 'da'. */
+#define TRUNNEL_DYNARRAY_GET(da, n) \
+ (((n) >= (da)->n_ ? (trunnel_abort(),0) : 0), (da)->elts_[(n)])
+#endif
+
+/** Change the 'n'th element of 'da' to 'v'. */
+#define TRUNNEL_DYNARRAY_SET(da, n, v) do { \
+ trunnel_assert((n) < (da)->n_); \
+ (da)->elts_[(n)] = (v); \
+ } while (0)
+
+/** Expand the dynamic array 'da' of 'elttype' so that it can hold at least
+ * 'howmanymore' elements than its current capacity. Always tries to increase
+ * the length of the array. On failure, run the code in 'on_fail' and goto
+ * trunnel_alloc_failed. */
+#define TRUNNEL_DYNARRAY_EXPAND(elttype, da, howmanymore, on_fail) do { \
+ elttype *newarray; \
+ newarray = trunnel_dynarray_expand(&(da)->allocated_, \
+ (da)->elts_, (howmanymore), \
+ sizeof(elttype)); \
+ if (newarray == NULL) { \
+ on_fail; \
+ goto trunnel_alloc_failed; \
+ } \
+ (da)->elts_ = newarray; \
+ } while (0)
+
+/** Add 'v' to the end of the dynamic array 'da' of 'elttype', expanding it if
+ * necessary. code in 'on_fail' and goto trunnel_alloc_failed. */
+#define TRUNNEL_DYNARRAY_ADD(elttype, da, v, on_fail) do { \
+ if ((da)->n_ == (da)->allocated_) { \
+ TRUNNEL_DYNARRAY_EXPAND(elttype, da, 1, on_fail); \
+ } \
+ (da)->elts_[(da)->n_++] = (v); \
+ } while (0)
+
+/** Return the number of elements in 'da'. */
+#define TRUNNEL_DYNARRAY_LEN(da) ((da)->n_)
+
+/** Remove all storage held by 'da' and set it to be empty. Does not free
+ * storage held by the elements themselves. */
+#define TRUNNEL_DYNARRAY_CLEAR(da) do { \
+ trunnel_free((da)->elts_); \
+ (da)->elts_ = NULL; \
+ (da)->n_ = (da)->allocated_ = 0; \
+ } while (0)
+
+/** Remove all storage held by 'da' and set it to be empty. Does not free
+ * storage held by the elements themselves. */
+#define TRUNNEL_DYNARRAY_WIPE(da) do { \
+ trunnel_memwipe((da)->elts_, (da)->allocated_ * sizeof((da)->elts_[0])); \
+ } while (0)
+
+/** Helper: wraps or implements an OpenBSD-style reallocarray. Behaves
+ * as realloc(a, x*y), but verifies that no overflow will occur in the
+ * multiplication. Returns NULL on failure. */
+#ifndef trunnel_reallocarray
+void *trunnel_reallocarray(void *a, size_t x, size_t y);
+#endif
+
+/** Helper to expand a dynamic array. Behaves as TRUNNEL_DYNARRAY_EXPAND(),
+ * taking the array of elements in 'ptr', a pointer to thethe current number
+ * of allocated elements in allocated_p, the minimum numbeer of elements to
+ * add in 'howmanymore', and the size of a single element in 'eltsize'.
+ *
+ * On success, adjust *allocated_p, and return the new value for the array of
+ * elements. On failure, adjust nothing and return NULL.
+ */
+void *trunnel_dynarray_expand(size_t *allocated_p, void *ptr,
+ size_t howmanymore, size_t eltsize);
+
+/** Type for a function to free members of a dynarray of pointers. */
+typedef void (*trunnel_free_fn_t)(void *);
+
+/**
+ * Helper to change the length of a dynamic array. Takes pointers to the
+ * current allocated and n fields of the array in 'allocated_p' and 'len_p',
+ * and the current array of elements in 'ptr'; takes the length of a single
+ * element in 'eltsize'. Changes the length to 'newlen'. If 'newlen' is
+ * greater than the current length, pads the new elements with 0. If newlen
+ * is less than the current length, and free_fn is non-NULL, treat the
+ * array as an array of void *, and invoke free_fn() on each removed element.
+ *
+ * On success, adjust *allocated_p and *len_p, and return the new value for
+ * the array of elements. On failure, adjust nothing, set *errcode_ptr to 1,
+ * and return NULL.
+ */
+void *trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p,
+ void *ptr, size_t newlen,
+ size_t eltsize, trunnel_free_fn_t free_fn,
+ uint8_t *errcode_ptr);
+
+/**
+ * Helper: return a pointer to the value of 'str' as a NUL-terminated string.
+ * Might have to reallocate the storage for 'str' in order to fit in the final
+ * NUL character. On allocation failure, return NULL.
+ */
+const char *trunnel_string_getstr(trunnel_string_t *str);
+
+/**
+ * Helper: change the contents of 'str' to hold the 'len'-byte string in
+ * 'inp'. Adjusts the storage to have a terminating NUL that doesn't count
+ * towards the length of the string. On success, return 0. On failure, set
+ * *errcode_ptr to 1 and return -1.
+ */
+int trunnel_string_setstr0(trunnel_string_t *str, const char *inp, size_t len,
+ uint8_t *errcode_ptr);
+
+/**
+ * As trunnel_dynarray_setlen, but adjusts a string rather than a dynamic
+ * array, and ensures that the new string is NUL-terminated.
+ */
+int trunnel_string_setlen(trunnel_string_t *str, size_t newlen,
+ uint8_t *errcode_ptr);
+
+#endif
+
+
+/*
+Copyright 2014 The Tor Project, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+ * Neither the names of the copyright owners nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/src/ext/trunnel/trunnel.c b/src/ext/trunnel/trunnel.c
new file mode 100644
index 0000000000..da4885ca01
--- /dev/null
+++ b/src/ext/trunnel/trunnel.c
@@ -0,0 +1,246 @@
+/* trunnel.c -- copied from Trunnel v1.2
+ * https://gitweb.torproject.org/trunnel.git
+ * You probably shouldn't edit this file.
+ */
+/* trunnel.c -- Helper functions to implement trunnel.
+ *
+ * Copyright 2014, The Tor Project, Inc.
+ * See license at the end of this file for copying information.
+ *
+ * See trunnel-impl.h for documentation of these functions.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "trunnel-impl.h"
+
+#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
+ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define IS_LITTLE_ENDIAN 1
+#elif defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && \
+ BYTE_ORDER == __ORDER_LITTLE_ENDIAN
+# define IS_LITTLE_ENDIAN 1
+#elif defined(_WIN32)
+# define IS_LITTLE_ENDIAN 1
+#elif defined(__APPLE__)
+# include <libkern/OSByteOrder.h>
+# define BSWAP64(x) OSSwapLittleToHostInt64(x)
+#elif defined(sun) || defined(__sun)
+# include <sys/byteorder.h>
+# ifndef _BIG_ENDIAN
+# define IS_LITTLE_ENDIAN
+# endif
+#else
+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/endian.h>
+# else
+# include <endian.h>
+# endif
+# if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+ __BYTE_ORDER == __LITTLE_ENDIAN
+# define IS_LITTLE_ENDIAN
+# endif
+#endif
+
+#ifdef _WIN32
+uint16_t
+trunnel_htons(uint16_t s)
+{
+ return (s << 8) | (s >> 8);
+}
+uint16_t
+trunnel_ntohs(uint16_t s)
+{
+ return (s << 8) | (s >> 8);
+}
+uint32_t
+trunnel_htonl(uint32_t s)
+{
+ return (s << 24) |
+ ((s << 8)&0xff0000) |
+ ((s >> 8)&0xff00) |
+ (s >> 24);
+}
+uint32_t
+trunnel_ntohl(uint32_t s)
+{
+ return (s << 24) |
+ ((s << 8)&0xff0000) |
+ ((s >> 8)&0xff00) |
+ (s >> 24);
+}
+#endif
+
+uint64_t
+trunnel_htonll(uint64_t a)
+{
+#ifdef IS_LITTLE_ENDIAN
+ return trunnel_htonl(a>>32) | (((uint64_t)trunnel_htonl(a))<<32);
+#else
+ return a;
+#endif
+}
+
+uint64_t
+trunnel_ntohll(uint64_t a)
+{
+ return trunnel_htonll(a);
+}
+
+#ifdef TRUNNEL_DEBUG_FAILING_ALLOC
+/** Used for debugging and running tricky test cases: Makes the nth
+ * memoryation allocation call from now fail.
+ */
+int trunnel_provoke_alloc_failure = 0;
+#endif
+
+void *
+trunnel_dynarray_expand(size_t *allocated_p, void *ptr,
+ size_t howmanymore, size_t eltsize)
+{
+ size_t newsize = howmanymore + *allocated_p;
+ void *newarray = NULL;
+ if (newsize < 8)
+ newsize = 8;
+ if (newsize < *allocated_p * 2)
+ newsize = *allocated_p * 2;
+ if (newsize <= *allocated_p || newsize < howmanymore)
+ return NULL;
+ newarray = trunnel_reallocarray(ptr, newsize, eltsize);
+ if (newarray == NULL)
+ return NULL;
+
+ *allocated_p = newsize;
+ return newarray;
+}
+
+#ifndef trunnel_reallocarray
+void *
+trunnel_reallocarray(void *a, size_t x, size_t y)
+{
+#ifdef TRUNNEL_DEBUG_FAILING_ALLOC
+ if (trunnel_provoke_alloc_failure) {
+ if (--trunnel_provoke_alloc_failure == 0)
+ return NULL;
+ }
+#endif
+ if (x > SIZE_MAX / y)
+ return NULL;
+ return trunnel_realloc(a, x * y);
+}
+#endif
+
+const char *
+trunnel_string_getstr(trunnel_string_t *str)
+{
+ trunnel_assert(str->allocated_ >= str->n_);
+ if (str->allocated_ == str->n_) {
+ TRUNNEL_DYNARRAY_EXPAND(char, str, 1, {});
+ }
+ str->elts_[str->n_] = 0;
+ return str->elts_;
+trunnel_alloc_failed:
+ return NULL;
+}
+
+int
+trunnel_string_setstr0(trunnel_string_t *str, const char *val, size_t len,
+ uint8_t *errcode_ptr)
+{
+ if (len == SIZE_MAX)
+ goto trunnel_alloc_failed;
+ if (str->allocated_ <= len) {
+ TRUNNEL_DYNARRAY_EXPAND(char, str, len + 1 - str->allocated_, {});
+ }
+ memcpy(str->elts_, val, len);
+ str->n_ = len;
+ str->elts_[len] = 0;
+ return 0;
+trunnel_alloc_failed:
+ *errcode_ptr = 1;
+ return -1;
+}
+
+int
+trunnel_string_setlen(trunnel_string_t *str, size_t newlen,
+ uint8_t *errcode_ptr)
+{
+ if (newlen == SIZE_MAX)
+ goto trunnel_alloc_failed;
+ if (str->allocated_ < newlen + 1) {
+ TRUNNEL_DYNARRAY_EXPAND(char, str, newlen + 1 - str->allocated_, {});
+ }
+ if (str->n_ < newlen) {
+ memset(& (str->elts_[str->n_]), 0, (newlen - str->n_));
+ }
+ str->n_ = newlen;
+ str->elts_[newlen] = 0;
+ return 0;
+
+ trunnel_alloc_failed:
+ *errcode_ptr = 1;
+ return -1;
+}
+
+void *
+trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p,
+ void *ptr, size_t newlen,
+ size_t eltsize, trunnel_free_fn_t free_fn,
+ uint8_t *errcode_ptr)
+{
+ if (*allocated_p < newlen) {
+ void *newptr = trunnel_dynarray_expand(allocated_p, ptr,
+ newlen - *allocated_p, eltsize);
+ if (newptr == NULL)
+ goto trunnel_alloc_failed;
+ ptr = newptr;
+ }
+ if (free_fn && *len_p > newlen) {
+ size_t i;
+ void **elts = (void **) ptr;
+ for (i = newlen; i < *len_p; ++i) {
+ free_fn(elts[i]);
+ elts[i] = NULL;
+ }
+ }
+ if (*len_p < newlen) {
+ memset( ((char*)ptr) + (eltsize * *len_p), 0, (newlen - *len_p) * eltsize);
+ }
+ *len_p = newlen;
+ return ptr;
+ trunnel_alloc_failed:
+ *errcode_ptr = 1;
+ return NULL;
+}
+
+/*
+Copyright 2014 The Tor Project, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+ * Neither the names of the copyright owners nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/src/ext/trunnel/trunnel.h b/src/ext/trunnel/trunnel.h
new file mode 100644
index 0000000000..f51cade03f
--- /dev/null
+++ b/src/ext/trunnel/trunnel.h
@@ -0,0 +1,64 @@
+/* trunnel.h -- copied from Trunnel v1.2
+ * https://gitweb.torproject.org/trunnel.git
+ * You probably shouldn't edit this file.
+ */
+/* trunnel.h -- Public declarations for trunnel, to be included
+ * in trunnel header files.
+
+ * Copyright 2014, The Tor Project, Inc.
+ * See license at the end of this file for copying information.
+ */
+
+#ifndef TRUNNEL_H_INCLUDED_
+#define TRUNNEL_H_INCLUDED_
+
+#include <sys/types.h>
+
+/** Macro to declare a variable-length dynamically allocated array. Trunnel
+ * uses these to store all variable-length arrays. */
+#define TRUNNEL_DYNARRAY_HEAD(name, elttype) \
+ struct name { \
+ size_t n_; \
+ size_t allocated_; \
+ elttype *elts_; \
+ }
+
+/** Initializer for a dynamic array of a given element type. */
+#define TRUNNEL_DYNARRAY_INIT(elttype) { 0, 0, (elttype*)NULL }
+
+/** Typedef used for storing variable-length arrays of char. */
+typedef TRUNNEL_DYNARRAY_HEAD(trunnel_string_st, char) trunnel_string_t;
+
+#endif
+
+/*
+Copyright 2014 The Tor Project, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+
+ * Neither the names of the copyright owners nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
diff --git a/src/include.am b/src/include.am
index d0693e25b0..c468af3649 100644
--- a/src/include.am
+++ b/src/include.am
@@ -1,7 +1,9 @@
include src/ext/include.am
+include src/trunnel/include.am
include src/common/include.am
include src/or/include.am
include src/test/include.am
include src/tools/include.am
include src/win32/include.am
include src/config/include.am
+
diff --git a/src/or/buffers.c b/src/or/buffers.c
index 033f86288e..d174f8147a 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -55,6 +55,9 @@
* forever.
*/
+static void socks_request_set_socks5_error(socks_request_t *req,
+ socks5_reply_status_t reason);
+
static int parse_socks(const char *data, size_t datalen, socks_request_t *req,
int log_sockstype, int safe_socks, ssize_t *drain_out,
size_t *want_length_out);
@@ -1831,6 +1834,21 @@ fetch_ext_or_command_from_evbuffer(struct evbuffer *buf, ext_or_cmd_t **out)
}
#endif
+/** Create a SOCKS5 reply message with <b>reason</b> in its REP field and
+ * have Tor send it as error response to <b>req</b>.
+ */
+static void
+socks_request_set_socks5_error(socks_request_t *req,
+ socks5_reply_status_t reason)
+{
+ req->replylen = 10;
+ memset(req->reply,0,10);
+
+ req->reply[0] = 0x05; // VER field.
+ req->reply[1] = reason; // REP field.
+ req->reply[3] = 0x01; // ATYP field.
+}
+
/** Implementation helper to implement fetch_from_*_socks. Instead of looking
* at a buffer's contents, we look at the <b>datalen</b> bytes of data in
* <b>data</b>. Instead of removing data from the buffer, we set
@@ -1966,6 +1984,8 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
req->command != SOCKS_COMMAND_RESOLVE &&
req->command != SOCKS_COMMAND_RESOLVE_PTR) {
/* not a connect or resolve or a resolve_ptr? we don't support it. */
+ socks_request_set_socks5_error(req,SOCKS5_COMMAND_NOT_SUPPORTED);
+
log_warn(LD_APP,"socks5: command %d not recognized. Rejecting.",
req->command);
return -1;
diff --git a/src/or/channel.c b/src/or/channel.c
index b2b670e4fb..c8c92633b1 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -108,8 +108,8 @@ channel_idmap_eq(const channel_idmap_entry_t *a,
HT_PROTOTYPE(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
channel_idmap_eq);
-HT_GENERATE(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
- channel_idmap_eq, 0.5, tor_malloc, tor_realloc, tor_free_);
+HT_GENERATE2(channel_idmap, channel_idmap_entry_s, node, channel_idmap_hash,
+ channel_idmap_eq, 0.5, tor_reallocarray_, tor_free_);
static cell_queue_entry_t * cell_queue_entry_dup(cell_queue_entry_t *q);
static void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off);
diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c
index 51a75cf502..59024abd12 100644
--- a/src/or/circpathbias.c
+++ b/src/or/circpathbias.c
@@ -1140,11 +1140,10 @@ pathbias_count_circs_in_states(entry_guard_t *guard,
path_state_t from,
path_state_t to)
{
- circuit_t *circ;
int open_circuits = 0;
/* Count currently open circuits. Give them the benefit of the doubt. */
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
origin_circuit_t *ocirc = NULL;
if (!CIRCUIT_IS_ORIGIN(circ) || /* didn't originate here */
circ->marked_for_close) /* already counted */
@@ -1167,6 +1166,7 @@ pathbias_count_circs_in_states(entry_guard_t *guard,
open_circuits++;
}
}
+ SMARTLIST_FOREACH_END(circ);
return open_circuits;
}
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 897f90fe4c..edf7d2863e 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1564,7 +1564,7 @@ choose_good_exit_server_general(int need_uptime, int need_capacity)
* -1 means "Don't use this router at all."
*/
the_nodes = nodelist_get_list();
- n_supported = tor_malloc(sizeof(int)*smartlist_len(the_nodes));
+ n_supported = tor_calloc(sizeof(int), smartlist_len(the_nodes));
SMARTLIST_FOREACH_BEGIN(the_nodes, const node_t *, node) {
const int i = node_sl_idx;
if (router_digest_is_me(node->identity)) {
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index f3a83503ef..9d72ea1111 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -21,6 +21,7 @@
#include "connection_edge.h"
#include "connection_or.h"
#include "control.h"
+#include "main.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "onion.h"
@@ -38,8 +39,7 @@
/********* START VARIABLES **********/
/** A global list of all circuits at this hop. */
-struct global_circuitlist_s global_circuitlist =
- TOR_LIST_HEAD_INITIALIZER(global_circuitlist);
+static smartlist_t *global_circuitlist = NULL;
/** A list of all the circuits in CIRCUIT_STATE_CHAN_WAIT. */
static smartlist_t *circuits_pending_chans = NULL;
@@ -94,9 +94,9 @@ static HT_HEAD(chan_circid_map, chan_circid_circuit_map_t)
chan_circid_map = HT_INITIALIZER();
HT_PROTOTYPE(chan_circid_map, chan_circid_circuit_map_t, node,
chan_circid_entry_hash_, chan_circid_entries_eq_)
-HT_GENERATE(chan_circid_map, chan_circid_circuit_map_t, node,
- chan_circid_entry_hash_, chan_circid_entries_eq_, 0.6,
- malloc, realloc, free)
+HT_GENERATE2(chan_circid_map, chan_circid_circuit_map_t, node,
+ chan_circid_entry_hash_, chan_circid_entries_eq_, 0.6,
+ tor_reallocarray_, tor_free_)
/** The most recently returned entry from circuit_get_by_circid_chan;
* used to improve performance when many cells arrive in a row from the
@@ -451,17 +451,25 @@ circuit_count_pending_on_channel(channel_t *chan)
void
circuit_close_all_marked(void)
{
- circuit_t *circ, *tmp;
- TOR_LIST_FOREACH_SAFE(circ, &global_circuitlist, head, tmp)
- if (circ->marked_for_close)
+ smartlist_t *lst = circuit_get_global_list();
+ SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, circ) {
+ /* Fix up index if SMARTLIST_DEL_CURRENT just moved this one. */
+ circ->global_circuitlist_idx = circ_sl_idx;
+ if (circ->marked_for_close) {
+ circ->global_circuitlist_idx = -1;
circuit_free(circ);
+ SMARTLIST_DEL_CURRENT(lst, circ);
+ }
+ } SMARTLIST_FOREACH_END(circ);
}
/** Return the head of the global linked list of circuits. */
-MOCK_IMPL(struct global_circuitlist_s *,
+MOCK_IMPL(smartlist_t *,
circuit_get_global_list,(void))
{
- return &global_circuitlist;
+ if (NULL == global_circuitlist)
+ global_circuitlist = smartlist_new();
+ return global_circuitlist;
}
/** Function to make circ-\>state human-readable */
@@ -678,7 +686,8 @@ init_circuit_base(circuit_t *circ)
circ->deliver_window = CIRCWINDOW_START;
cell_queue_init(&circ->n_chan_cells);
- TOR_LIST_INSERT_HEAD(&global_circuitlist, circ, head);
+ smartlist_add(circuit_get_global_list(), circ);
+ circ->global_circuitlist_idx = smartlist_len(circuit_get_global_list()) - 1;
}
/** Allocate space for a new circuit, initializing with <b>p_circ_id</b>
@@ -799,7 +808,16 @@ circuit_free(circuit_t *circ)
extend_info_free(circ->n_hop);
tor_free(circ->n_chan_create_cell);
- TOR_LIST_REMOVE(circ, head);
+ if (circ->global_circuitlist_idx != -1) {
+ int idx = circ->global_circuitlist_idx;
+ circuit_t *c2 = smartlist_get(global_circuitlist, idx);
+ tor_assert(c2 == circ);
+ smartlist_del(global_circuitlist, idx);
+ if (idx < smartlist_len(global_circuitlist)) {
+ c2 = smartlist_get(global_circuitlist, idx);
+ c2->global_circuitlist_idx = idx;
+ }
+ }
/* Remove from map. */
circuit_set_n_circid_chan(circ, 0, NULL);
@@ -841,9 +859,9 @@ circuit_clear_cpath(origin_circuit_t *circ)
void
circuit_free_all(void)
{
- circuit_t *tmp, *tmp2;
+ smartlist_t *lst = circuit_get_global_list();
- TOR_LIST_FOREACH_SAFE(tmp, &global_circuitlist, head, tmp2) {
+ SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, tmp) {
if (! CIRCUIT_IS_ORIGIN(tmp)) {
or_circuit_t *or_circ = TO_OR_CIRCUIT(tmp);
while (or_circ->resolving_streams) {
@@ -853,8 +871,13 @@ circuit_free_all(void)
or_circ->resolving_streams = next_conn;
}
}
+ tmp->global_circuitlist_idx = -1;
circuit_free(tmp);
- }
+ SMARTLIST_DEL_CURRENT(lst, tmp);
+ } SMARTLIST_FOREACH_END(tmp);
+
+ smartlist_free(lst);
+ global_circuitlist = NULL;
smartlist_free(circuits_pending_chans);
circuits_pending_chans = NULL;
@@ -932,10 +955,9 @@ circuit_dump_conn_details(int severity,
void
circuit_dump_by_conn(connection_t *conn, int severity)
{
- circuit_t *circ;
edge_connection_t *tmpconn;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
if (circ->marked_for_close) {
@@ -966,6 +988,7 @@ circuit_dump_by_conn(connection_t *conn, int severity)
}
}
}
+ SMARTLIST_FOREACH_END(circ);
}
/** Return the circuit whose global ID is <b>id</b>, or NULL if no
@@ -973,8 +996,7 @@ circuit_dump_by_conn(connection_t *conn, int severity)
origin_circuit_t *
circuit_get_by_global_id(uint32_t id)
{
- circuit_t *circ;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (CIRCUIT_IS_ORIGIN(circ) &&
TO_ORIGIN_CIRCUIT(circ)->global_identifier == id) {
if (circ->marked_for_close)
@@ -983,6 +1005,7 @@ circuit_get_by_global_id(uint32_t id)
return TO_ORIGIN_CIRCUIT(circ);
}
}
+ SMARTLIST_FOREACH_END(circ);
return NULL;
}
@@ -1151,17 +1174,17 @@ circuit_unlink_all_from_channel(channel_t *chan, int reason)
#ifdef DEBUG_CIRCUIT_UNLINK_ALL
{
- circuit_t *circ;
smartlist_t *detached_2 = smartlist_new();
int mismatch = 0, badlen = 0;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (circ->n_chan == chan ||
(!CIRCUIT_IS_ORIGIN(circ) &&
TO_OR_CIRCUIT(circ)->p_chan == chan)) {
smartlist_add(detached_2, circ);
}
}
+ SMARTLIST_FOREACH_END(circ);
if (smartlist_len(detached) != smartlist_len(detached_2)) {
log_warn(LD_BUG, "List of detached circuits had the wrong length! "
@@ -1235,8 +1258,7 @@ circuit_unlink_all_from_channel(channel_t *chan, int reason)
origin_circuit_t *
circuit_get_ready_rend_circ_by_rend_data(const rend_data_t *rend_data)
{
- circuit_t *circ;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!circ->marked_for_close &&
circ->purpose == CIRCUIT_PURPOSE_C_REND_READY) {
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
@@ -1249,6 +1271,7 @@ circuit_get_ready_rend_circ_by_rend_data(const rend_data_t *rend_data)
return ocirc;
}
}
+ SMARTLIST_FOREACH_END(circ);
return NULL;
}
@@ -1261,14 +1284,17 @@ origin_circuit_t *
circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
const char *digest, uint8_t purpose)
{
- circuit_t *circ;
+ int idx;
+ smartlist_t *lst = circuit_get_global_list();
tor_assert(CIRCUIT_PURPOSE_IS_ORIGIN(purpose));
if (start == NULL)
- circ = TOR_LIST_FIRST(&global_circuitlist);
+ idx = 0;
else
- circ = TOR_LIST_NEXT(TO_CIRCUIT(start), head);
+ idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
+
+ for ( ; idx < smartlist_len(lst); ++idx) {
+ circuit_t *circ = smartlist_get(lst, idx);
- for ( ; circ; circ = TOR_LIST_NEXT(circ, head)) {
if (circ->marked_for_close)
continue;
if (circ->purpose != purpose)
@@ -1469,7 +1495,6 @@ origin_circuit_t *
circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
int flags)
{
- circuit_t *circ_;
origin_circuit_t *best=NULL;
int need_uptime = (flags & CIRCLAUNCH_NEED_UPTIME) != 0;
int need_capacity = (flags & CIRCLAUNCH_NEED_CAPACITY) != 0;
@@ -1485,7 +1510,7 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
"capacity %d, internal %d",
purpose, need_uptime, need_capacity, internal);
- TOR_LIST_FOREACH(circ_, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ_) {
if (CIRCUIT_IS_ORIGIN(circ_) &&
circ_->state == CIRCUIT_STATE_OPEN &&
!circ_->marked_for_close &&
@@ -1535,6 +1560,7 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
}
}
}
+ SMARTLIST_FOREACH_END(circ_);
return best;
}
@@ -1574,13 +1600,13 @@ circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
void
circuit_mark_all_unused_circs(void)
{
- circuit_t *circ;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (CIRCUIT_IS_ORIGIN(circ) &&
!circ->marked_for_close &&
!circ->timestamp_dirty)
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
}
+ SMARTLIST_FOREACH_END(circ);
}
/** Go through the circuitlist; for each circuit that starts at us
@@ -1593,14 +1619,14 @@ circuit_mark_all_unused_circs(void)
void
circuit_mark_all_dirty_circs_as_unusable(void)
{
- circuit_t *circ;
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (CIRCUIT_IS_ORIGIN(circ) &&
!circ->marked_for_close &&
circ->timestamp_dirty) {
mark_circuit_unusable_for_new_conns(TO_ORIGIN_CIRCUIT(circ));
}
}
+ SMARTLIST_FOREACH_END(circ);
}
/** Mark <b>circ</b> to be closed next time we call
@@ -1799,6 +1825,29 @@ marked_circuit_free_cells(circuit_t *circ)
cell_queue_clear(& TO_OR_CIRCUIT(circ)->p_chan_cells);
}
+static size_t
+single_conn_free_bytes(connection_t *conn)
+{
+ size_t result = 0;
+ if (conn->inbuf) {
+ result += buf_allocation(conn->inbuf);
+ buf_clear(conn->inbuf);
+ }
+ if (conn->outbuf) {
+ result += buf_allocation(conn->outbuf);
+ buf_clear(conn->outbuf);
+ }
+ if (conn->type == CONN_TYPE_DIR) {
+ dir_connection_t *dir_conn = TO_DIR_CONN(conn);
+ if (dir_conn->zlib_state) {
+ result += tor_zlib_state_size(dir_conn->zlib_state);
+ tor_zlib_free(dir_conn->zlib_state);
+ dir_conn->zlib_state = NULL;
+ }
+ }
+ return result;
+}
+
/** Aggressively free buffer contents on all the buffers of all streams in the
* list starting at <b>stream</b>. Return the number of bytes recovered. */
static size_t
@@ -1807,13 +1856,9 @@ marked_circuit_streams_free_bytes(edge_connection_t *stream)
size_t result = 0;
for ( ; stream; stream = stream->next_stream) {
connection_t *conn = TO_CONN(stream);
- if (conn->inbuf) {
- result += buf_allocation(conn->inbuf);
- buf_clear(conn->inbuf);
- }
- if (conn->outbuf) {
- result += buf_allocation(conn->outbuf);
- buf_clear(conn->outbuf);
+ result += single_conn_free_bytes(conn);
+ if (conn->linked_conn) {
+ result += single_conn_free_bytes(conn->linked_conn);
}
}
return result;
@@ -1871,6 +1916,28 @@ circuit_max_queued_cell_age(const circuit_t *c, uint32_t now)
return age;
}
+/** Return the age in milliseconds of the oldest buffer chunk on <b>conn</b>,
+ * where age is taken in milliseconds before the time <b>now</b> (in truncated
+ * milliseconds since the epoch). If the connection has no data, treat
+ * it as having age zero.
+ **/
+static uint32_t
+conn_get_buffer_age(const connection_t *conn, uint32_t now)
+{
+ uint32_t age = 0, age2;
+ if (conn->outbuf) {
+ age2 = buf_get_oldest_chunk_timestamp(conn->outbuf, now);
+ if (age2 > age)
+ age = age2;
+ }
+ if (conn->inbuf) {
+ age2 = buf_get_oldest_chunk_timestamp(conn->inbuf, now);
+ if (age2 > age)
+ age = age2;
+ }
+ return age;
+}
+
/** Return the age in milliseconds of the oldest buffer chunk on any stream in
* the linked list <b>stream</b>, where age is taken in milliseconds before
* the time <b>now</b> (in truncated milliseconds since the epoch). */
@@ -1880,18 +1947,15 @@ circuit_get_streams_max_data_age(const edge_connection_t *stream, uint32_t now)
uint32_t age = 0, age2;
for (; stream; stream = stream->next_stream) {
const connection_t *conn = TO_CONN(stream);
- if (conn->outbuf) {
- age2 = buf_get_oldest_chunk_timestamp(conn->outbuf, now);
- if (age2 > age)
- age = age2;
- }
- if (conn->inbuf) {
- age2 = buf_get_oldest_chunk_timestamp(conn->inbuf, now);
+ age2 = conn_get_buffer_age(conn, now);
+ if (age2 > age)
+ age = age2;
+ if (conn->linked_conn) {
+ age2 = conn_get_buffer_age(conn->linked_conn, now);
if (age2 > age)
age = age2;
}
}
-
return age;
}
@@ -1942,6 +2006,26 @@ circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
return -1;
}
+static uint32_t now_ms_for_buf_cmp;
+
+/** Helper to sort a list of circuit_t by age of oldest item, in descending
+ * order. */
+static int
+conns_compare_by_buffer_age_(const void **a_, const void **b_)
+{
+ const connection_t *a = *a_;
+ const connection_t *b = *b_;
+ time_t age_a = conn_get_buffer_age(a, now_ms_for_buf_cmp);
+ time_t age_b = conn_get_buffer_age(b, now_ms_for_buf_cmp);
+
+ if (age_a < age_b)
+ return 1;
+ else if (age_a == age_b)
+ return 0;
+ else
+ return -1;
+}
+
#define FRACTION_OF_DATA_TO_RETAIN_ON_OOM 0.90
/** We're out of memory for cells, having allocated <b>current_allocation</b>
@@ -1950,12 +2034,13 @@ circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
void
circuits_handle_oom(size_t current_allocation)
{
- /* Let's hope there's enough slack space for this allocation here... */
- smartlist_t *circlist = smartlist_new();
- circuit_t *circ;
+ smartlist_t *circlist;
+ smartlist_t *connection_array = get_connection_array();
+ int conn_idx;
size_t mem_to_recover;
size_t mem_recovered=0;
int n_circuits_killed=0;
+ int n_dirconns_killed=0;
struct timeval now;
uint32_t now_ms;
log_notice(LD_GENERAL, "We're low on memory. Killing circuits with "
@@ -1984,22 +2069,61 @@ circuits_handle_oom(size_t current_allocation)
tor_gettimeofday_cached_monotonic(&now);
now_ms = (uint32_t)tv_to_msec(&now);
- /* This algorithm itself assumes that you've got enough memory slack
- * to actually run it. */
- TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
+ circlist = circuit_get_global_list();
+ SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
circ->age_tmp = circuit_max_queued_item_age(circ, now_ms);
- smartlist_add(circlist, circ);
- }
+ } SMARTLIST_FOREACH_END(circ);
/* This is O(n log n); there are faster algorithms we could use instead.
* Let's hope this doesn't happen enough to be in the critical path. */
smartlist_sort(circlist, circuits_compare_by_oldest_queued_item_);
- /* Okay, now the worst circuits are at the front of the list. Let's mark
- * them, and reclaim their storage aggressively. */
+ /* Fix up the indices before we run into trouble */
SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
- size_t n = n_cells_in_circ_queues(circ);
+ circ->global_circuitlist_idx = circ_sl_idx;
+ } SMARTLIST_FOREACH_END(circ);
+
+ /* Now sort the connection array ... */
+ now_ms_for_buf_cmp = now_ms;
+ smartlist_sort(connection_array, conns_compare_by_buffer_age_);
+ now_ms_for_buf_cmp = 0;
+
+ /* Fix up the connection array to its new order. */
+ SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
+ conn->conn_array_index = conn_sl_idx;
+ } SMARTLIST_FOREACH_END(conn);
+
+ /* Okay, now the worst circuits and connections are at the front of their
+ * respective lists. Let's mark them, and reclaim their storage
+ * aggressively. */
+ conn_idx = 0;
+ SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
+ size_t n;
size_t freed;
+
+ /* Free storage in any non-linked directory connections that have buffered
+ * data older than this circuit. */
+ while (conn_idx < smartlist_len(connection_array)) {
+ connection_t *conn = smartlist_get(connection_array, conn_idx);
+ uint32_t conn_age = conn_get_buffer_age(conn, now_ms);
+ if (conn_age < circ->age_tmp) {
+ break;
+ }
+ if (conn->type == CONN_TYPE_DIR && conn->linked_conn == NULL) {
+ if (!conn->marked_for_close)
+ connection_mark_for_close(conn);
+ mem_recovered += single_conn_free_bytes(conn);
+
+ ++n_dirconns_killed;
+
+ if (mem_recovered >= mem_to_recover)
+ goto done_recovering_mem;
+ }
+ ++conn_idx;
+ }
+
+ /* Now, kill the circuit. */
+ n = n_cells_in_circ_queues(circ);
if (! circ->marked_for_close) {
circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
}
@@ -2012,9 +2136,11 @@ circuits_handle_oom(size_t current_allocation)
mem_recovered += freed;
if (mem_recovered >= mem_to_recover)
- break;
+ goto done_recovering_mem;
} SMARTLIST_FOREACH_END(circ);
+ done_recovering_mem:
+
#ifdef ENABLE_MEMPOOLS
clean_cell_pool(); /* In case this helps. */
#endif /* ENABLE_MEMPOOLS */
@@ -2022,12 +2148,12 @@ circuits_handle_oom(size_t current_allocation)
chunks. */
log_notice(LD_GENERAL, "Removed "U64_FORMAT" bytes by killing %d circuits; "
- "%d circuits remain alive.",
+ "%d circuits remain alive. Also killed %d non-linked directory "
+ "connections.",
U64_PRINTF_ARG(mem_recovered),
n_circuits_killed,
- smartlist_len(circlist) - n_circuits_killed);
-
- smartlist_free(circlist);
+ smartlist_len(circlist) - n_circuits_killed,
+ n_dirconns_killed);
}
/** Verify that cpath layer <b>cp</b> has all of its invariants
diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h
index d48d7c3963..03934f971e 100644
--- a/src/or/circuitlist.h
+++ b/src/or/circuitlist.h
@@ -14,9 +14,7 @@
#include "testsupport.h"
-TOR_LIST_HEAD(global_circuitlist_s, circuit_t);
-
-MOCK_DECL(struct global_circuitlist_s*, circuit_get_global_list, (void));
+MOCK_DECL(smartlist_t *, circuit_get_global_list, (void));
const char *circuit_state_to_string(int state);
const char *circuit_purpose_to_controller_string(uint8_t purpose);
const char *circuit_purpose_to_controller_hs_state_string(uint8_t purpose);
diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c
index e4571ff944..3ca33b03ce 100644
--- a/src/or/circuitmux.c
+++ b/src/or/circuitmux.c
@@ -363,9 +363,9 @@ HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t);
/* Emit a bunch of hash table stuff */
HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
chanid_circid_entry_hash, chanid_circid_entries_eq);
-HT_GENERATE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
- chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
- malloc, realloc, free);
+HT_GENERATE2(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
+ chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
+ tor_reallocarray_, tor_free_)
/*
* Circuitmux alloc/free functions
diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c
index e362b1b49e..5336e4046e 100644
--- a/src/or/circuitstats.c
+++ b/src/or/circuitstats.c
@@ -404,7 +404,7 @@ circuit_build_times_new_consensus_params(circuit_build_times_t *cbt,
* distress anyway, so memory correctness here is paramount over
* doing acrobatics to preserve the array.
*/
- recent_circs = tor_malloc_zero(sizeof(int8_t)*num);
+ recent_circs = tor_calloc(sizeof(int8_t), num);
if (cbt->liveness.timeouts_after_firsthop &&
cbt->liveness.num_recent_circs > 0) {
memcpy(recent_circs, cbt->liveness.timeouts_after_firsthop,
@@ -508,7 +508,7 @@ circuit_build_times_init(circuit_build_times_t *cbt)
cbt->liveness.num_recent_circs =
circuit_build_times_recent_circuit_count(NULL);
cbt->liveness.timeouts_after_firsthop =
- tor_malloc_zero(sizeof(int8_t)*cbt->liveness.num_recent_circs);
+ tor_calloc(sizeof(int8_t), cbt->liveness.num_recent_circs);
} else {
cbt->liveness.num_recent_circs = 0;
cbt->liveness.timeouts_after_firsthop = NULL;
@@ -649,7 +649,7 @@ circuit_build_times_create_histogram(const circuit_build_times_t *cbt,
int i, c;
*nbins = 1 + (max_build_time / CBT_BIN_WIDTH);
- histogram = tor_malloc_zero(*nbins * sizeof(build_time_t));
+ histogram = tor_calloc(*nbins, sizeof(build_time_t));
// calculate histogram
for (i = 0; i < CBT_NCIRCUITS_TO_OBSERVE; i++) {
@@ -691,7 +691,7 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
if (cbt->total_build_times < CBT_NCIRCUITS_TO_OBSERVE)
num_modes = 1;
- nth_max_bin = (build_time_t*)tor_malloc_zero(num_modes*sizeof(build_time_t));
+ nth_max_bin = tor_calloc(num_modes, sizeof(build_time_t));
/* Determine the N most common build times */
for (i = 0; i < nbins; i++) {
@@ -873,7 +873,7 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt,
}
/* build_time_t 0 means uninitialized */
- loaded_times = tor_malloc_zero(sizeof(build_time_t)*state->TotalBuildTimes);
+ loaded_times = tor_calloc(sizeof(build_time_t), state->TotalBuildTimes);
for (line = state->BuildtimeHistogram; line; line = line->next) {
smartlist_t *args = smartlist_new();
@@ -1085,7 +1085,21 @@ circuit_build_times_calculate_timeout(circuit_build_times_t *cbt,
tor_assert(1.0-quantile > 0);
tor_assert(cbt->Xm > 0);
- ret = cbt->Xm/pow(1.0-quantile,1.0/cbt->alpha);
+ /* If either alpha or p are 0, we would divide by zero, yielding an
+ * infinite (double) result; which would be clamped to INT32_MAX.
+ * Instead, initialise ret to INT32_MAX, and skip over these
+ * potentially illegal/trapping divides by zero.
+ */
+ ret = INT32_MAX;
+
+ if (cbt->alpha > 0) {
+ double p;
+ p = pow(1.0-quantile,1.0/cbt->alpha);
+ if (p > 0) {
+ ret = cbt->Xm/p;
+ }
+ }
+
if (ret > INT32_MAX) {
ret = INT32_MAX;
}
@@ -1371,10 +1385,11 @@ circuit_build_times_network_check_changed(circuit_build_times_t *cbt)
}
cbt->liveness.after_firsthop_idx = 0;
+#define MAX_TIMEOUT ((int32_t) (INT32_MAX/2))
/* Check to see if this has happened before. If so, double the timeout
* to give people on abysmally bad network connections a shot at access */
if (cbt->timeout_ms >= circuit_build_times_get_initial_timeout()) {
- if (cbt->timeout_ms > INT32_MAX/2 || cbt->close_ms > INT32_MAX/2) {
+ if (cbt->timeout_ms > MAX_TIMEOUT || cbt->close_ms > MAX_TIMEOUT) {
log_warn(LD_CIRC, "Insanely large circuit build timeout value. "
"(timeout = %fmsec, close = %fmsec)",
cbt->timeout_ms, cbt->close_ms);
@@ -1386,6 +1401,7 @@ circuit_build_times_network_check_changed(circuit_build_times_t *cbt)
cbt->close_ms = cbt->timeout_ms
= circuit_build_times_get_initial_timeout();
}
+#undef MAX_TIMEOUT
cbt_control_event_buildtimeout_set(cbt, BUILDTIMEOUT_SET_EVENT_RESET);
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 714754a672..9ea0023568 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -268,7 +268,6 @@ circuit_get_best(const entry_connection_t *conn,
int must_be_open, uint8_t purpose,
int need_uptime, int need_internal)
{
- circuit_t *circ;
origin_circuit_t *best=NULL;
struct timeval now;
int intro_going_on_but_too_old = 0;
@@ -281,7 +280,7 @@ circuit_get_best(const entry_connection_t *conn,
tor_gettimeofday(&now);
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
origin_circuit_t *origin_circ;
if (!CIRCUIT_IS_ORIGIN(circ))
continue;
@@ -305,6 +304,7 @@ circuit_get_best(const entry_connection_t *conn,
if (!best || circuit_is_better(origin_circ,best,conn))
best = origin_circ;
}
+ SMARTLIST_FOREACH_END(circ);
if (!best && intro_going_on_but_too_old)
log_info(LD_REND|LD_CIRC, "There is an intro circuit being created "
@@ -318,11 +318,9 @@ circuit_get_best(const entry_connection_t *conn,
static int
count_pending_general_client_circuits(void)
{
- const circuit_t *circ;
-
int count = 0;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (circ->marked_for_close ||
circ->state == CIRCUIT_STATE_OPEN ||
circ->purpose != CIRCUIT_PURPOSE_C_GENERAL ||
@@ -331,6 +329,7 @@ count_pending_general_client_circuits(void)
++count;
}
+ SMARTLIST_FOREACH_END(circ);
return count;
}
@@ -370,7 +369,6 @@ circuit_conforms_to_options(const origin_circuit_t *circ,
void
circuit_expire_building(void)
{
- circuit_t *victim, *next_circ;
/* circ_times.timeout_ms and circ_times.close_ms are from
* circuit_build_times_get_initial_timeout() if we haven't computed
* custom timeouts yet */
@@ -388,7 +386,7 @@ circuit_expire_building(void)
* we want to be more lenient with timeouts, in case the
* user has relocated and/or changed network connections.
* See bug #3443. */
- TOR_LIST_FOREACH(next_circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, next_circ) {
if (!CIRCUIT_IS_ORIGIN(next_circ) || /* didn't originate here */
next_circ->marked_for_close) { /* don't mess with marked circs */
continue;
@@ -402,7 +400,7 @@ circuit_expire_building(void)
any_opened_circs = 1;
break;
}
- }
+ } SMARTLIST_FOREACH_END(next_circ);
#define SET_CUTOFF(target, msec) do { \
long ms = tor_lround(msec); \
@@ -473,9 +471,8 @@ circuit_expire_building(void)
MAX(get_circuit_build_close_time_ms()*2 + 1000,
options->SocksTimeout * 1000));
- TOR_LIST_FOREACH(next_circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *,victim) {
struct timeval cutoff;
- victim = next_circ;
if (!CIRCUIT_IS_ORIGIN(victim) || /* didn't originate here */
victim->marked_for_close) /* don't mess with marked circs */
continue;
@@ -780,7 +777,7 @@ circuit_expire_building(void)
circuit_mark_for_close(victim, END_CIRC_REASON_TIMEOUT);
pathbias_count_timeout(TO_ORIGIN_CIRCUIT(victim));
- }
+ } SMARTLIST_FOREACH_END(victim);
}
/** For debugging #8387: track when we last called
@@ -800,9 +797,8 @@ circuit_log_ancient_one_hop_circuits(int age)
time_t cutoff = now - age;
int n_found = 0;
smartlist_t *log_these = smartlist_new();
- const circuit_t *circ;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
const origin_circuit_t *ocirc;
if (! CIRCUIT_IS_ORIGIN(circ))
continue;
@@ -817,6 +813,7 @@ circuit_log_ancient_one_hop_circuits(int age)
smartlist_add(log_these, (origin_circuit_t*) ocirc);
}
}
+ SMARTLIST_FOREACH_END(circ);
if (n_found == 0)
goto done;
@@ -831,7 +828,7 @@ circuit_log_ancient_one_hop_circuits(int age)
int stream_num;
const edge_connection_t *conn;
char *dirty = NULL;
- circ = TO_CIRCUIT(ocirc);
+ const circuit_t *circ = TO_CIRCUIT(ocirc);
format_local_iso_time(created,
(time_t)circ->timestamp_created.tv_sec);
@@ -938,7 +935,6 @@ int
circuit_stream_is_being_handled(entry_connection_t *conn,
uint16_t port, int min)
{
- circuit_t *circ;
const node_t *exitnode;
int num=0;
time_t now = time(NULL);
@@ -946,7 +942,7 @@ circuit_stream_is_being_handled(entry_connection_t *conn,
get_options()->LongLivedPorts,
conn ? conn->socks_request->port : port);
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (CIRCUIT_IS_ORIGIN(circ) &&
!circ->marked_for_close &&
circ->purpose == CIRCUIT_PURPOSE_C_GENERAL &&
@@ -976,6 +972,7 @@ circuit_stream_is_being_handled(entry_connection_t *conn,
}
}
}
+ SMARTLIST_FOREACH_END(circ);
return 0;
}
@@ -989,7 +986,6 @@ circuit_stream_is_being_handled(entry_connection_t *conn,
static void
circuit_predict_and_launch_new(void)
{
- circuit_t *circ;
int num=0, num_internal=0, num_uptime_internal=0;
int hidserv_needs_uptime=0, hidserv_needs_capacity=1;
int port_needs_uptime=0, port_needs_capacity=1;
@@ -997,7 +993,7 @@ circuit_predict_and_launch_new(void)
int flags = 0;
/* First, count how many of each type of circuit we have already. */
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
cpath_build_state_t *build_state;
origin_circuit_t *origin_circ;
if (!CIRCUIT_IS_ORIGIN(circ))
@@ -1020,6 +1016,7 @@ circuit_predict_and_launch_new(void)
if (build_state->need_uptime && build_state->is_internal)
num_uptime_internal++;
}
+ SMARTLIST_FOREACH_END(circ);
/* If that's enough, then stop now. */
if (num >= MAX_UNUSED_OPEN_CIRCUITS)
@@ -1223,7 +1220,6 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
static void
circuit_expire_old_circuits_clientside(void)
{
- circuit_t *circ;
struct timeval cutoff, now;
tor_gettimeofday(&now);
@@ -1239,7 +1235,7 @@ circuit_expire_old_circuits_clientside(void)
cutoff.tv_sec -= get_options()->CircuitIdleTimeout;
}
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (circ->marked_for_close || !CIRCUIT_IS_ORIGIN(circ))
continue;
/* If the circuit has been dirty for too long, and there are no streams
@@ -1291,7 +1287,7 @@ circuit_expire_old_circuits_clientside(void)
}
}
}
- }
+ } SMARTLIST_FOREACH_END(circ);
}
/** How long do we wait before killing circuits with the properties
@@ -1318,11 +1314,10 @@ circuit_expire_old_circuits_clientside(void)
void
circuit_expire_old_circuits_serverside(time_t now)
{
- circuit_t *circ;
or_circuit_t *or_circ;
time_t cutoff = now - IDLE_ONE_HOP_CIRC_TIMEOUT;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (circ->marked_for_close || CIRCUIT_IS_ORIGIN(circ))
continue;
or_circ = TO_OR_CIRCUIT(circ);
@@ -1339,6 +1334,7 @@ circuit_expire_old_circuits_serverside(time_t now)
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
}
}
+ SMARTLIST_FOREACH_END(circ);
}
/** Number of testing circuits we want open before testing our bandwidth. */
@@ -1363,18 +1359,18 @@ reset_bandwidth_test(void)
int
circuit_enough_testing_circs(void)
{
- circuit_t *circ;
int num = 0;
if (have_performed_bandwidth_test)
return 1;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!circ->marked_for_close && CIRCUIT_IS_ORIGIN(circ) &&
circ->purpose == CIRCUIT_PURPOSE_TESTING &&
circ->state == CIRCUIT_STATE_OPEN)
num++;
}
+ SMARTLIST_FOREACH_END(circ);
return num >= NUM_PARALLEL_TESTING_CIRCS;
}
@@ -2074,7 +2070,7 @@ static void
link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ,
crypt_path_t *cpath)
{
- const node_t *exitnode;
+ const node_t *exitnode = NULL;
/* add it into the linked list of streams on this circuit */
log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %u.",
@@ -2108,23 +2104,25 @@ link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ,
circ->isolation_any_streams_attached = 1;
connection_edge_update_circuit_isolation(apconn, circ, 0);
+ /* Compute the exitnode if possible, for logging below */
+ if (cpath->extend_info)
+ exitnode = node_get_by_id(cpath->extend_info->identity_digest);
+
/* See if we can use optimistic data on this circuit */
- if (cpath->extend_info &&
- (exitnode = node_get_by_id(cpath->extend_info->identity_digest)) &&
- exitnode->rs) {
- /* Okay; we know what exit node this is. */
- if (optimistic_data_enabled() &&
- circ->base_.purpose == CIRCUIT_PURPOSE_C_GENERAL &&
- exitnode->rs->version_supports_optimistic_data)
- apconn->may_use_optimistic_data = 1;
- else
- apconn->may_use_optimistic_data = 0;
- log_info(LD_APP, "Looks like completed circuit to %s %s allow "
- "optimistic data for connection to %s",
- safe_str_client(node_describe(exitnode)),
- apconn->may_use_optimistic_data ? "does" : "doesn't",
- safe_str_client(apconn->socks_request->address));
- }
+ if (optimistic_data_enabled() &&
+ (circ->base_.purpose == CIRCUIT_PURPOSE_C_GENERAL ||
+ circ->base_.purpose == CIRCUIT_PURPOSE_C_REND_JOINED))
+ apconn->may_use_optimistic_data = 1;
+ else
+ apconn->may_use_optimistic_data = 0;
+ log_info(LD_APP, "Looks like completed circuit to %s %s allow "
+ "optimistic data for connection to %s",
+ circ->base_.purpose == CIRCUIT_PURPOSE_C_GENERAL ?
+ /* node_describe() does the right thing if exitnode is NULL */
+ safe_str_client(node_describe(exitnode)) :
+ "hidden service",
+ apconn->may_use_optimistic_data ? "does" : "doesn't",
+ safe_str_client(apconn->socks_request->address));
}
/** Return true iff <b>address</b> is matched by one of the entries in
diff --git a/src/or/config.c b/src/or/config.c
index 39b85aa1ab..d620f585fe 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -99,8 +99,6 @@ static config_abbrev_t option_abbrevs_[] = {
{ "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
{ "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
{ "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
- { "StrictEntryNodes", "StrictNodes", 0, 1},
- { "StrictExitNodes", "StrictNodes", 0, 1},
{ "VirtualAddrNetwork", "VirtualAddrNetworkIPv4", 0, 0},
{ "_UseFilteringSSLBufferevents", "UseFilteringSSLBufferevents", 0, 1},
{ NULL, NULL, 0, 0},
@@ -127,8 +125,8 @@ static config_abbrev_t option_abbrevs_[] = {
* be chosen first.
*/
static config_var_t option_vars_[] = {
- OBSOLETE("AccountingMaxKB"),
V(AccountingMax, MEMUNIT, "0 bytes"),
+ VAR("AccountingRule", STRING, AccountingRule_option, "max"),
V(AccountingStart, STRING, NULL),
V(Address, STRING, NULL),
V(AllowDotExit, BOOL, "0"),
@@ -140,8 +138,8 @@ static config_var_t option_vars_[] = {
V(AlternateDirAuthority, LINELIST, NULL),
OBSOLETE("AlternateHSAuthority"),
V(AssumeReachable, BOOL, "0"),
- V(AuthDirBadDir, LINELIST, NULL),
- V(AuthDirBadDirCCs, CSV, ""),
+ OBSOLETE("AuthDirBadDir"),
+ OBSOLETE("AuthDirBadDirCCs"),
V(AuthDirBadExit, LINELIST, NULL),
V(AuthDirBadExitCCs, CSV, ""),
V(AuthDirInvalid, LINELIST, NULL),
@@ -150,8 +148,8 @@ static config_var_t option_vars_[] = {
V(AuthDirGuardBWGuarantee, MEMUNIT, "2 MB"),
V(AuthDirReject, LINELIST, NULL),
V(AuthDirRejectCCs, CSV, ""),
- V(AuthDirRejectUnlisted, BOOL, "0"),
- V(AuthDirListBadDirs, BOOL, "0"),
+ OBSOLETE("AuthDirRejectUnlisted"),
+ OBSOLETE("AuthDirListBadDirs"),
V(AuthDirListBadExits, BOOL, "0"),
V(AuthDirMaxServersPerAddr, UINT, "2"),
V(AuthDirMaxServersPerAuthAddr,UINT, "5"),
@@ -196,21 +194,14 @@ static config_var_t option_vars_[] = {
V(CookieAuthFile, STRING, NULL),
V(CountPrivateBandwidth, BOOL, "0"),
V(DataDirectory, FILENAME, NULL),
- OBSOLETE("DebugLogFile"),
V(DisableNetwork, BOOL, "0"),
V(DirAllowPrivateAddresses, BOOL, "0"),
V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
V(DirListenAddress, LINELIST, NULL),
- OBSOLETE("DirFetchPeriod"),
V(DirPolicy, LINELIST, NULL),
VPORT(DirPort, LINELIST, NULL),
V(DirPortFrontPage, FILENAME, NULL),
- OBSOLETE("DirPostPeriod"),
- OBSOLETE("DirRecordUsageByCountry"),
- OBSOLETE("DirRecordUsageGranularity"),
- OBSOLETE("DirRecordUsageRetainIPs"),
- OBSOLETE("DirRecordUsageSaveInterval"),
- V(DirReqStatistics, BOOL, "1"),
+ VAR("DirReqStatistics", BOOL, DirReqStatistics_option, "1"),
VAR("DirAuthority", LINELIST, DirAuthorities, NULL),
V(DirAuthorityFallbackRate, DOUBLE, "1.0"),
V(DisableAllSwap, BOOL, "0"),
@@ -262,7 +253,6 @@ static config_var_t option_vars_[] = {
V(GeoIPv6File, FILENAME,
SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip6"),
#endif
- OBSOLETE("GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays"),
OBSOLETE("Group"),
V(GuardLifetime, INTERVAL, "0 minutes"),
V(HardwareAccel, BOOL, "0"),
@@ -272,15 +262,11 @@ static config_var_t option_vars_[] = {
V(HashedControlPassword, LINELIST, NULL),
V(HidServDirectoryV2, BOOL, "1"),
VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
- OBSOLETE("HiddenServiceExcludeNodes"),
- OBSOLETE("HiddenServiceNodes"),
VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
VAR("HiddenServiceAuthorizeClient",LINELIST_S,RendConfigLines, NULL),
V(HidServAuth, LINELIST, NULL),
- OBSOLETE("HSAuthoritativeDir"),
- OBSOLETE("HSAuthorityRecordStats"),
V(CloseHSClientCircuitsImmediatelyOnTimeout, BOOL, "0"),
V(CloseHSServiceRendCircuitsImmediatelyOnTimeout, BOOL, "0"),
V(HTTPProxy, STRING, NULL),
@@ -295,14 +281,11 @@ static config_var_t option_vars_[] = {
V(Socks5Proxy, STRING, NULL),
V(Socks5ProxyUsername, STRING, NULL),
V(Socks5ProxyPassword, STRING, NULL),
- OBSOLETE("IgnoreVersion"),
V(KeepalivePeriod, INTERVAL, "5 minutes"),
VAR("Log", LINELIST, Logs, NULL),
V(LogMessageDomains, BOOL, "0"),
- OBSOLETE("LinkPadding"),
- OBSOLETE("LogLevel"),
- OBSOLETE("LogFile"),
V(LogTimeGranularity, MSEC_INTERVAL, "1 second"),
+ V(TruncateLogFile, BOOL, "0"),
V(LongLivedPorts, CSV,
"21,22,706,1863,5050,5190,5222,5223,6523,6667,6697,8300"),
VAR("MapAddress", LINELIST, AddressMap, NULL),
@@ -313,16 +296,14 @@ static config_var_t option_vars_[] = {
OBSOLETE("MaxOnionsPending"),
V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"),
- OBSOLETE("MonthlyAccountingStart"),
V(MyFamily, STRING, NULL),
V(NewCircuitPeriod, INTERVAL, "30 seconds"),
- VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
+ OBSOLETE("NamingAuthoritativeDirectory"),
V(NATDListenAddress, LINELIST, NULL),
VPORT(NATDPort, LINELIST, NULL),
V(Nickname, STRING, NULL),
V(PredictedPortsRelevanceTime, INTERVAL, "1 hour"),
V(WarnUnsafeSocks, BOOL, "1"),
- OBSOLETE("NoPublish"),
VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
V(NumCPUs, UINT, "0"),
V(NumDirectoryGuards, UINT, "0"),
@@ -348,7 +329,6 @@ static config_var_t option_vars_[] = {
V(PathBiasScaleUseThreshold, INT, "-1"),
V(PathsNeededToBuildCircuits, DOUBLE, "-1"),
- OBSOLETE("PathlenCoinWeight"),
V(PerConnBWBurst, MEMUNIT, "0"),
V(PerConnBWRate, MEMUNIT, "0"),
V(PidFile, STRING, NULL),
@@ -368,18 +348,13 @@ static config_var_t option_vars_[] = {
V(RecommendedVersions, LINELIST, NULL),
V(RecommendedClientVersions, LINELIST, NULL),
V(RecommendedServerVersions, LINELIST, NULL),
- OBSOLETE("RedirectExit"),
V(RefuseUnknownExits, AUTOBOOL, "auto"),
V(RejectPlaintextPorts, CSV, ""),
V(RelayBandwidthBurst, MEMUNIT, "0"),
V(RelayBandwidthRate, MEMUNIT, "0"),
- OBSOLETE("RendExcludeNodes"),
- OBSOLETE("RendNodes"),
V(RendPostPeriod, INTERVAL, "1 hour"),
V(RephistTrackTime, INTERVAL, "24 hours"),
- OBSOLETE("RouterFile"),
V(RunAsDaemon, BOOL, "0"),
-// V(RunTesting, BOOL, "0"),
OBSOLETE("RunTesting"), // currently unused
V(Sandbox, BOOL, "0"),
V(SafeLogging, STRING, "1"),
@@ -398,18 +373,16 @@ static config_var_t option_vars_[] = {
VPORT(SocksPort, LINELIST, NULL),
V(SocksTimeout, INTERVAL, "2 minutes"),
V(SSLKeyLifetime, INTERVAL, "0"),
- OBSOLETE("StatusFetchPeriod"),
+ OBSOLETE("StrictEntryNodes"),
+ OBSOLETE("StrictExitNodes"),
V(StrictNodes, BOOL, "0"),
V(Support022HiddenServices, AUTOBOOL, "auto"),
- OBSOLETE("SysLog"),
V(TestSocks, BOOL, "0"),
- OBSOLETE("TestVia"),
V(TokenBucketRefillInterval, MSEC_INTERVAL, "100 msec"),
V(Tor2webMode, BOOL, "0"),
V(TLSECGroup, STRING, NULL),
V(TrackHostExits, CSV, NULL),
V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
- OBSOLETE("TrafficShaping"),
V(TransListenAddress, LINELIST, NULL),
VPORT(TransPort, LINELIST, NULL),
V(TransProxyType, STRING, "default"),
@@ -558,7 +531,8 @@ static int check_server_ports(const smartlist_t *ports,
static int validate_data_directory(or_options_t *options);
static int write_configuration_file(const char *fname,
const or_options_t *options);
-static int options_init_logs(or_options_t *options, int validate_only);
+static int options_init_logs(const or_options_t *old_options,
+ or_options_t *options, int validate_only);
static void init_libevent(const or_options_t *options);
static int opt_streq(const char *s1, const char *s2);
@@ -1146,7 +1120,8 @@ options_act_reversible(const or_options_t *old_options, char **msg)
mark_logs_temp(); /* Close current logs once new logs are open. */
logs_marked = 1;
- if (options_init_logs(options, 0)<0) { /* Configure the tor_log(s) */
+ /* Configure the tor_log(s) */
+ if (options_init_logs(old_options, options, 0)<0) {
*msg = tor_strdup("Failed to init Log options. See logs for details.");
goto rollback;
}
@@ -1425,24 +1400,26 @@ options_act(const or_options_t *old_options)
mark_transport_list();
pt_prepare_proxy_list_for_config_read();
- if (options->ClientTransportPlugin) {
- for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
- if (parse_client_transport_line(options, cl->value, 0)<0) {
- log_warn(LD_BUG,
- "Previously validated ClientTransportPlugin line "
- "could not be added!");
- return -1;
+ if (!options->DisableNetwork) {
+ if (options->ClientTransportPlugin) {
+ for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
+ if (parse_client_transport_line(options, cl->value, 0)<0) {
+ log_warn(LD_BUG,
+ "Previously validated ClientTransportPlugin line "
+ "could not be added!");
+ return -1;
+ }
}
}
- }
- if (options->ServerTransportPlugin && server_mode(options)) {
- for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
- if (parse_server_transport_line(options, cl->value, 0)<0) {
- log_warn(LD_BUG,
- "Previously validated ServerTransportPlugin line "
- "could not be added!");
- return -1;
+ if (options->ServerTransportPlugin && server_mode(options)) {
+ for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
+ if (parse_server_transport_line(options, cl->value, 0)<0) {
+ log_warn(LD_BUG,
+ "Previously validated ServerTransportPlugin line "
+ "could not be added!");
+ return -1;
+ }
}
}
}
@@ -1593,6 +1570,20 @@ options_act(const or_options_t *old_options)
return -1;
}
+ config_maybe_load_geoip_files_(options, old_options);
+
+ if (geoip_is_loaded(AF_INET) && options->GeoIPExcludeUnknown) {
+ /* ExcludeUnknown is true or "auto" */
+ const int is_auto = options->GeoIPExcludeUnknown == -1;
+ int changed;
+
+ changed = routerset_add_unknown_ccs(&options->ExcludeNodes, is_auto);
+ changed += routerset_add_unknown_ccs(&options->ExcludeExitNodes, is_auto);
+
+ if (changed)
+ routerset_add_unknown_ccs(&options->ExcludeExitNodesUnion_, is_auto);
+ }
+
/* Check for transitions that need action. */
if (old_options) {
int revise_trackexithosts = 0;
@@ -1688,19 +1679,9 @@ options_act(const or_options_t *old_options)
connection_or_update_token_buckets(get_connection_array(), options);
}
- config_maybe_load_geoip_files_(options, old_options);
-
- if (geoip_is_loaded(AF_INET) && options->GeoIPExcludeUnknown) {
- /* ExcludeUnknown is true or "auto" */
- const int is_auto = options->GeoIPExcludeUnknown == -1;
- int changed;
-
- changed = routerset_add_unknown_ccs(&options->ExcludeNodes, is_auto);
- changed += routerset_add_unknown_ccs(&options->ExcludeExitNodes, is_auto);
-
- if (changed)
- routerset_add_unknown_ccs(&options->ExcludeExitNodesUnion_, is_auto);
- }
+ /* Only collect directory-request statistics on relays and bridges. */
+ options->DirReqStatistics = options->DirReqStatistics_option &&
+ server_mode(options);
if (options->CellStatistics || options->DirReqStatistics ||
options->EntryStatistics || options->ExitPortStatistics ||
@@ -1709,11 +1690,6 @@ options_act(const or_options_t *old_options)
time_t now = time(NULL);
int print_notice = 0;
- /* Only collect directory-request statistics on relays and bridges. */
- if (!server_mode(options)) {
- options->DirReqStatistics = 0;
- }
-
/* Only collect other relay-only statistics on relays. */
if (!public_server_mode(options)) {
options->CellStatistics = 0;
@@ -1732,8 +1708,8 @@ options_act(const or_options_t *old_options)
geoip_dirreq_stats_init(now);
print_notice = 1;
} else {
+ /* disable statistics collection since we have no geoip file */
options->DirReqStatistics = 0;
- /* Don't warn Tor clients, they don't use statistics */
if (options->ORPort_set)
log_notice(LD_CONFIG, "Configured to measure directory request "
"statistics, but no GeoIP database found. "
@@ -2549,7 +2525,8 @@ options_validate(or_options_t *old_options, or_options_t *options,
config_line_append(&options->Logs, "Log", "warn stdout");
}
- if (options_init_logs(options, 1)<0) /* Validate the tor_log(s) */
+ /* Validate the tor_log(s) */
+ if (options_init_logs(old_options, options, 1)<0)
REJECT("Failed to validate Log options. See logs for details.");
if (authdir_mode(options)) {
@@ -3135,6 +3112,16 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
}
+ options->AccountingRule = ACCT_MAX;
+ if (options->AccountingRule_option) {
+ if (!strcmp(options->AccountingRule_option, "sum"))
+ options->AccountingRule = ACCT_SUM;
+ else if (!strcmp(options->AccountingRule_option, "max"))
+ options->AccountingRule = ACCT_MAX;
+ else
+ REJECT("AccountingRule must be 'sum' or 'max'");
+ }
+
if (options->HTTPProxy) { /* parse it now */
if (tor_addr_port_lookup(options->HTTPProxy,
&options->HTTPProxyAddr, &options->HTTPProxyPort) < 0)
@@ -3183,11 +3170,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
}
- /* Check if more than one proxy type has been enabled. */
+ /* Check if more than one exclusive proxy type has been enabled. */
if (!!options->Socks4Proxy + !!options->Socks5Proxy +
- !!options->HTTPSProxy + !!options->ClientTransportPlugin > 1)
+ !!options->HTTPSProxy > 1)
REJECT("You have configured more than one proxy type. "
- "(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)");
+ "(Socks4Proxy|Socks5Proxy|HTTPSProxy)");
/* Check if the proxies will give surprising behavior. */
if (options->HTTPProxy && !(options->Socks4Proxy ||
@@ -4455,7 +4442,8 @@ addressmap_register_auto(const char *from, const char *to,
* Initialize the logs based on the configuration file.
*/
static int
-options_init_logs(or_options_t *options, int validate_only)
+options_init_logs(const or_options_t *old_options, or_options_t *options,
+ int validate_only)
{
config_line_t *opt;
int ok;
@@ -4548,7 +4536,21 @@ options_init_logs(or_options_t *options, int validate_only)
!strcasecmp(smartlist_get(elts,0), "file")) {
if (!validate_only) {
char *fname = expand_filename(smartlist_get(elts, 1));
- if (add_file_log(severity, fname) < 0) {
+ /* Truncate if TruncateLogFile is set and we haven't seen this option
+ line before. */
+ int truncate = 0;
+ if (options->TruncateLogFile) {
+ truncate = 1;
+ if (old_options) {
+ config_line_t *opt2;
+ for (opt2 = old_options->Logs; opt2; opt2 = opt2->next)
+ if (!strcmp(opt->value, opt2->value)) {
+ truncate = 0;
+ break;
+ }
+ }
+ }
+ if (add_file_log(severity, fname, truncate) < 0) {
log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s",
opt->value, strerror(errno));
ok = 0;
@@ -4837,7 +4839,7 @@ parse_client_transport_line(const or_options_t *options,
if (!validate_only && !is_useless_proxy) {
proxy_argc = line_length-2;
tor_assert(proxy_argc > 0);
- proxy_argv = tor_malloc_zero(sizeof(char*)*(proxy_argc+1));
+ proxy_argv = tor_calloc(sizeof(char *), (proxy_argc + 1));
tmp = proxy_argv;
for (i=0;i<proxy_argc;i++) { /* store arguments */
*tmp++ = smartlist_get(items, 2);
@@ -4849,6 +4851,13 @@ parse_client_transport_line(const or_options_t *options,
pt_kickstart_client_proxy(transport_list, proxy_argv);
}
} else { /* external */
+ /* ClientTransportPlugins connecting through a proxy is managed only. */
+ if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
+ log_warn(LD_CONFIG, "You have configured an external proxy with another "
+ "proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
+ goto err;
+ }
+
if (smartlist_len(transport_list) != 1) {
log_warn(LD_CONFIG, "You can't have an external proxy with "
"more than one transports.");
@@ -5117,7 +5126,7 @@ parse_server_transport_line(const or_options_t *options,
if (!validate_only) {
proxy_argc = line_length-2;
tor_assert(proxy_argc > 0);
- proxy_argv = tor_malloc_zero(sizeof(char*)*(proxy_argc+1));
+ proxy_argv = tor_calloc(sizeof(char *), (proxy_argc + 1));
tmp = proxy_argv;
for (i=0;i<proxy_argc;i++) { /* store arguments */
diff --git a/src/or/connection.c b/src/or/connection.c
index 276dca2818..4a3bd2cf03 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1688,14 +1688,14 @@ get_proxy_type(void)
{
const or_options_t *options = get_options();
- if (options->HTTPSProxy)
+ if (options->ClientTransportPlugin)
+ return PROXY_PLUGGABLE;
+ else if (options->HTTPSProxy)
return PROXY_CONNECT;
else if (options->Socks4Proxy)
return PROXY_SOCKS4;
else if (options->Socks5Proxy)
return PROXY_SOCKS5;
- else if (options->ClientTransportPlugin)
- return PROXY_PLUGGABLE;
else
return PROXY_NONE;
}
@@ -3716,9 +3716,15 @@ connection_handle_write_impl(connection_t *conn, int force)
if (connection_state_is_connecting(conn)) {
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) {
log_warn(LD_BUG, "getsockopt() syscall failed");
- if (CONN_IS_EDGE(conn))
- connection_edge_end_errno(TO_EDGE_CONN(conn));
- connection_mark_for_close(conn);
+ if (conn->type == CONN_TYPE_OR) {
+ or_connection_t *orconn = TO_OR_CONN(conn);
+ connection_or_close_for_error(orconn, 0);
+ } else {
+ if (CONN_IS_EDGE(conn)) {
+ connection_edge_end_errno(TO_EDGE_CONN(conn));
+ }
+ connection_mark_for_close(conn);
+ }
return -1;
}
if (e) {
@@ -4781,6 +4787,27 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
{
const or_options_t *options = get_options();
+ /* Client Transport Plugins can use another proxy, but that should be hidden
+ * from the rest of tor (as the plugin is responsible for dealing with the
+ * proxy), check it first, then check the rest of the proxy types to allow
+ * the config to have unused ClientTransportPlugin entries.
+ */
+ if (options->ClientTransportPlugin) {
+ const transport_t *transport = NULL;
+ int r;
+ r = get_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
+ if (r<0)
+ return -1;
+ if (transport) { /* transport found */
+ tor_addr_copy(addr, &transport->addr);
+ *port = transport->port;
+ *proxy_type = transport->socks_version;
+ return 0;
+ }
+
+ /* Unused ClientTransportPlugin. */
+ }
+
if (options->HTTPSProxy) {
tor_addr_copy(addr, &options->HTTPSProxyAddr);
*port = options->HTTPSProxyPort;
@@ -4796,19 +4823,6 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
*port = options->Socks5ProxyPort;
*proxy_type = PROXY_SOCKS5;
return 0;
- } else if (options->ClientTransportPlugin ||
- options->Bridges) {
- const transport_t *transport = NULL;
- int r;
- r = get_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
- if (r<0)
- return -1;
- if (transport) { /* transport found */
- tor_addr_copy(addr, &transport->addr);
- *port = transport->port;
- *proxy_type = transport->socks_version;
- return 0;
- }
}
tor_addr_make_unspec(addr);
@@ -4832,7 +4846,7 @@ log_failed_proxy_connection(connection_t *conn)
log_warn(LD_NET,
"The connection to the %s proxy server at %s just failed. "
"Make sure that the proxy server is up and running.",
- proxy_type_to_string(get_proxy_type()),
+ proxy_type_to_string(proxy_type),
fmt_addrport(&proxy_addr, proxy_port));
}
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 49f9ba4978..522807d7ba 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1767,7 +1767,8 @@ connection_ap_supports_optimistic_data(const entry_connection_t *conn)
general circuit. */
if (edge_conn->on_circuit == NULL ||
edge_conn->on_circuit->state != CIRCUIT_STATE_OPEN ||
- edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_GENERAL)
+ (edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_GENERAL &&
+ edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_REND_JOINED))
return 0;
return conn->may_use_optimistic_data;
@@ -2764,7 +2765,6 @@ connection_exit_connect(edge_connection_t *edge_conn)
/* also, deliver a 'connected' cell back through the circuit. */
if (connection_edge_is_rendezvous_stream(edge_conn)) {
- /* rendezvous stream */
/* don't send an address back! */
connection_edge_send_command(edge_conn,
RELAY_COMMAND_CONNECTED,
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index c372270b4c..7fcc5b24d6 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -908,18 +908,11 @@ connection_or_init_conn_from_address(or_connection_t *conn,
tor_free(conn->base_.address);
conn->base_.address = tor_dup_addr(&node_ap.addr);
} else {
- const char *n;
- /* If we're an authoritative directory server, we may know a
- * nickname for this router. */
- n = dirserv_get_nickname_by_digest(id_digest);
- if (n) {
- conn->nickname = tor_strdup(n);
- } else {
- conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
- conn->nickname[0] = '$';
- base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
- conn->identity_digest, DIGEST_LEN);
- }
+ conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
+ conn->nickname[0] = '$';
+ base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
+ conn->identity_digest, DIGEST_LEN);
+
tor_free(conn->base_.address);
conn->base_.address = tor_dup_addr(addr);
}
diff --git a/src/or/control.c b/src/or/control.c
index 9378f38f40..92dd2309ed 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -47,6 +47,7 @@
#include <sys/resource.h>
#endif
+#include "crypto_s2k.h"
#include "procmon.h"
/** Yield true iff <b>s</b> is the state of a control_connection_t that has
@@ -194,14 +195,14 @@ log_severity_to_event(int severity)
static void
clear_circ_bw_fields(void)
{
- circuit_t *circ;
origin_circuit_t *ocirc;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!CIRCUIT_IS_ORIGIN(circ))
continue;
ocirc = TO_ORIGIN_CIRCUIT(circ);
ocirc->n_written_circ_bw = ocirc->n_read_circ_bw = 0;
}
+ SMARTLIST_FOREACH_END(circ);
}
/** Set <b>global_event_mask*</b> to the bitwise OR of each live control
@@ -949,7 +950,7 @@ static int
handle_control_setevents(control_connection_t *conn, uint32_t len,
const char *body)
{
- int event_code = -1;
+ int event_code;
event_mask_t event_mask = 0;
smartlist_t *events = smartlist_new();
@@ -963,6 +964,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
continue;
} else {
int i;
+ event_code = -1;
+
for (i = 0; control_event_table[i].event_name != NULL; ++i) {
if (!strcasecmp(ev, control_event_table[i].event_name)) {
event_code = control_event_table[i].event_code;
@@ -993,7 +996,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
/** Decode the hashed, base64'd passwords stored in <b>passwords</b>.
* Return a smartlist of acceptable passwords (unterminated strings of
- * length S2K_SPECIFIER_LEN+DIGEST_LEN) on success, or NULL on failure.
+ * length S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) on success, or NULL on
+ * failure.
*/
smartlist_t *
decode_hashed_passwords(config_line_t *passwords)
@@ -1009,16 +1013,17 @@ decode_hashed_passwords(config_line_t *passwords)
if (!strcmpstart(hashed, "16:")) {
if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))<0
- || strlen(hashed+3) != (S2K_SPECIFIER_LEN+DIGEST_LEN)*2) {
+ || strlen(hashed+3) != (S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN)*2) {
goto err;
}
} else {
if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
- != S2K_SPECIFIER_LEN+DIGEST_LEN) {
+ != S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) {
goto err;
}
}
- smartlist_add(sl, tor_memdup(decoded, S2K_SPECIFIER_LEN+DIGEST_LEN));
+ smartlist_add(sl,
+ tor_memdup(decoded, S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN));
}
return sl;
@@ -1039,7 +1044,7 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
{
int used_quoted_string = 0;
const or_options_t *options = get_options();
- const char *errstr = NULL;
+ const char *errstr = "Unknown error";
char *password;
size_t password_len;
const char *cp;
@@ -1160,22 +1165,27 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
}
if (bad) {
if (!also_cookie) {
- log_warn(LD_CONTROL,
+ log_warn(LD_BUG,
"Couldn't decode HashedControlPassword: invalid base16");
errstr="Couldn't decode HashedControlPassword value in configuration.";
+ goto err;
}
bad_password = 1;
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_free(sl);
+ sl = NULL;
} else {
SMARTLIST_FOREACH(sl, char *, expected,
{
- secret_to_key(received,DIGEST_LEN,password,password_len,expected);
- if (tor_memeq(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
+ secret_to_key_rfc2440(received,DIGEST_LEN,
+ password,password_len,expected);
+ if (tor_memeq(expected + S2K_RFC2440_SPECIFIER_LEN,
+ received, DIGEST_LEN))
goto ok;
});
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_free(sl);
+ sl = NULL;
if (used_quoted_string)
errstr = "Password did not match HashedControlPassword value from "
@@ -1198,9 +1208,12 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
err:
tor_free(password);
- connection_printf_to_buf(conn, "515 Authentication failed: %s\r\n",
- errstr ? errstr : "Unknown reason.");
+ connection_printf_to_buf(conn, "515 Authentication failed: %s\r\n", errstr);
connection_mark_for_close(TO_CONN(conn));
+ if (sl) { /* clean up */
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+ smartlist_free(sl);
+ }
return 0;
ok:
log_info(LD_CONTROL, "Authenticated control connection ("TOR_SOCKET_T_FORMAT
@@ -1879,9 +1892,8 @@ getinfo_helper_events(control_connection_t *control_conn,
{
(void) control_conn;
if (!strcmp(question, "circuit-status")) {
- circuit_t *circ_;
smartlist_t *status = smartlist_new();
- TOR_LIST_FOREACH(circ_, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ_) {
origin_circuit_t *circ;
char *circdesc;
const char *state;
@@ -1903,6 +1915,7 @@ getinfo_helper_events(control_connection_t *control_conn,
state, *circdesc ? " " : "", circdesc);
tor_free(circdesc);
}
+ SMARTLIST_FOREACH_END(circ_);
*answer = smartlist_join_strings(status, "\r\n", 0, NULL);
SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
smartlist_free(status);
@@ -3909,12 +3922,11 @@ control_event_stream_bandwidth_used(void)
int
control_event_circ_bandwidth_used(void)
{
- circuit_t *circ;
origin_circuit_t *ocirc;
if (!EVENT_IS_INTERESTING(EVENT_CIRC_BANDWIDTH_USED))
return 0;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!CIRCUIT_IS_ORIGIN(circ))
continue;
ocirc = TO_ORIGIN_CIRCUIT(circ);
@@ -3927,6 +3939,7 @@ control_event_circ_bandwidth_used(void)
(unsigned long)ocirc->n_written_circ_bw);
ocirc->n_written_circ_bw = ocirc->n_read_circ_bw = 0;
}
+ SMARTLIST_FOREACH_END(circ);
return 0;
}
@@ -4091,14 +4104,13 @@ format_cell_stats(char **event_string, circuit_t *circ,
int
control_event_circuit_cell_stats(void)
{
- circuit_t *circ;
cell_stats_t *cell_stats;
char *event_string;
if (!get_options()->TestingEnableCellStatsEvent ||
!EVENT_IS_INTERESTING(EVENT_CELL_STATS))
return 0;
cell_stats = tor_malloc(sizeof(cell_stats_t));;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!circ->testing_cell_stats)
continue;
sum_up_cell_stats_by_command(circ, cell_stats);
@@ -4107,6 +4119,7 @@ control_event_circuit_cell_stats(void)
"650 CELL_STATS %s\r\n", event_string);
tor_free(event_string);
}
+ SMARTLIST_FOREACH_END(circ);
tor_free(cell_stats);
return 0;
}
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 61b2c29b38..94138f8c1e 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -414,12 +414,6 @@ cpuworker_main(void *data)
cpuworker_reply_t rpl;
fd = fdarray[1]; /* this side is ours */
-#ifndef TOR_IS_MULTITHREADED
- tor_close_socket(fdarray[0]); /* this is the side of the socketpair the
- * parent uses */
- tor_free_all(1); /* so the child doesn't hold the parent's fd's open */
- handle_signals(0); /* ignore interrupts from the keyboard, etc */
-#endif
tor_free(data);
setup_server_onion_keys(&onion_keys);
@@ -516,7 +510,7 @@ spawn_cpuworker(void)
connection_t *conn;
int err;
- fdarray = tor_malloc(sizeof(tor_socket_t)*2);
+ fdarray = tor_calloc(sizeof(tor_socket_t), 2);
if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fdarray)) < 0) {
log_warn(LD_NET, "Couldn't construct socketpair for cpuworker: %s",
tor_socket_strerror(-err));
@@ -535,10 +529,6 @@ spawn_cpuworker(void)
return -1;
}
log_debug(LD_OR,"just spawned a cpu worker.");
-#ifndef TOR_IS_MULTITHREADED
- tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */
- tor_free(fdarray);
-#endif
conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX);
diff --git a/src/or/directory.c b/src/or/directory.c
index 298271f366..1aaa75ccee 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -197,9 +197,9 @@ dir_conn_purpose_to_string(int purpose)
return "(unknown)";
}
-/** Return true iff <b>identity_digest</b> is the digest of a router we
- * believe to support extrainfo downloads. (If <b>is_authority</b> we do
- * additional checking that's only valid for authorities.) */
+/** Return true iff <b>identity_digest</b> is the digest of a router which
+ * says that it caches extrainfos. (If <b>is_authority</b> we always
+ * believe that to be true.) */
int
router_supports_extrainfo(const char *identity_digest, int is_authority)
{
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 49fafafab2..374cfa6f40 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -56,13 +56,11 @@ static int routers_with_measured_bw = 0;
static void directory_remove_invalid(void);
static char *format_versions_list(config_line_t *ln);
struct authdir_config_t;
-static int add_fingerprint_to_dir(const char *nickname, const char *fp,
- struct authdir_config_t *list);
static uint32_t
dirserv_get_status_impl(const char *fp, const char *nickname,
uint32_t addr, uint16_t or_port,
- const char *platform, const char *contact,
- const char **msg, int should_log);
+ const char *platform, const char **msg,
+ int should_log);
static void clear_cached_dir(cached_dir_t *d);
static const signed_descriptor_t *get_signed_descriptor_by_fp(
const char *fp,
@@ -75,19 +73,19 @@ static uint32_t dirserv_get_credible_bandwidth_kb(const routerinfo_t *ri);
/************** Fingerprint handling code ************/
-#define FP_NAMED 1 /**< Listed in fingerprint file. */
+/* 1 Historically used to indicate Named */
#define FP_INVALID 2 /**< Believed invalid. */
#define FP_REJECT 4 /**< We will not publish this router. */
-#define FP_BADDIR 8 /**< We'll tell clients to avoid using this as a dir. */
+/* 8 Historically used to avoid using this as a dir. */
#define FP_BADEXIT 16 /**< We'll tell clients not to use this as an exit. */
-#define FP_UNNAMED 32 /**< Another router has this name in fingerprint file. */
+/* 32 Historically used to indicade Unnamed */
-/** Encapsulate a nickname and an FP_* status; target of status_by_digest
- * map. */
-typedef struct router_status_t {
- char nickname[MAX_NICKNAME_LEN+1];
- uint32_t status;
-} router_status_t;
+/** Target of status_by_digest map. */
+typedef uint32_t router_status_t;
+
+static void add_fingerprint_to_dir(const char *fp,
+ struct authdir_config_t *list,
+ router_status_t add_status);
/** List of nickname-\>identity fingerprint mappings for all the routers
* that we name. Used to prevent router impersonation. */
@@ -109,18 +107,17 @@ authdir_config_new(void)
return list;
}
-/** Add the fingerprint <b>fp</b> for <b>nickname</b> to
- * the smartlist of fingerprint_entry_t's <b>list</b>. Return 0 if it's
- * new, or 1 if we replaced the old value.
+/** Add the fingerprint <b>fp</b> to the smartlist of fingerprint_entry_t's
+ * <b>list</b>, or-ing the currently set status flags with
+ * <b>add_status</b>.
*/
-/* static */ int
-add_fingerprint_to_dir(const char *nickname, const char *fp,
- authdir_config_t *list)
+/* static */ void
+add_fingerprint_to_dir(const char *fp, authdir_config_t *list,
+ router_status_t add_status)
{
char *fingerprint;
char d[DIGEST_LEN];
router_status_t *status;
- tor_assert(nickname);
tor_assert(fp);
tor_assert(list);
@@ -130,14 +127,7 @@ add_fingerprint_to_dir(const char *nickname, const char *fp,
log_warn(LD_DIRSERV, "Couldn't decode fingerprint \"%s\"",
escaped(fp));
tor_free(fingerprint);
- return 0;
- }
-
- if (!strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME)) {
- log_warn(LD_DIRSERV, "Tried to add a mapping for reserved nickname %s",
- UNNAMED_ROUTER_NICKNAME);
- tor_free(fingerprint);
- return 0;
+ return;
}
status = digestmap_get(list->status_by_digest, d);
@@ -146,35 +136,15 @@ add_fingerprint_to_dir(const char *nickname, const char *fp,
digestmap_set(list->status_by_digest, d, status);
}
- if (nickname[0] != '!') {
- char *old_fp = strmap_get_lc(list->fp_by_name, nickname);
- if (old_fp && !strcasecmp(fingerprint, old_fp)) {
- tor_free(fingerprint);
- } else {
- tor_free(old_fp);
- strmap_set_lc(list->fp_by_name, nickname, fingerprint);
- }
- status->status |= FP_NAMED;
- strlcpy(status->nickname, nickname, sizeof(status->nickname));
- } else {
- tor_free(fingerprint);
- if (!strcasecmp(nickname, "!reject")) {
- status->status |= FP_REJECT;
- } else if (!strcasecmp(nickname, "!invalid")) {
- status->status |= FP_INVALID;
- } else if (!strcasecmp(nickname, "!baddir")) {
- status->status |= FP_BADDIR;
- } else if (!strcasecmp(nickname, "!badexit")) {
- status->status |= FP_BADEXIT;
- }
- }
- return 0;
+ tor_free(fingerprint);
+ *status |= add_status;
+ return;
}
-/** Add the nickname and fingerprint for this OR to the
- * global list of recognized identity key fingerprints. */
+/** Add the fingerprint for this OR to the global list of recognized
+ * identity key fingerprints. */
int
-dirserv_add_own_fingerprint(const char *nickname, crypto_pk_t *pk)
+dirserv_add_own_fingerprint(crypto_pk_t *pk)
{
char fp[FINGERPRINT_LEN+1];
if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
@@ -183,7 +153,7 @@ dirserv_add_own_fingerprint(const char *nickname, crypto_pk_t *pk)
}
if (!fingerprint_list)
fingerprint_list = authdir_config_new();
- add_fingerprint_to_dir(nickname, fp, fingerprint_list);
+ add_fingerprint_to_dir(fp, fingerprint_list, 0);
return 0;
}
@@ -201,7 +171,6 @@ dirserv_load_fingerprint_file(void)
authdir_config_t *fingerprint_list_new;
int result;
config_line_t *front=NULL, *list;
- const or_options_t *options = get_options();
fname = get_datadir_fname("approved-routers");
log_info(LD_GENERAL,
@@ -209,15 +178,9 @@ dirserv_load_fingerprint_file(void)
cf = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
if (!cf) {
- if (options->NamingAuthoritativeDir) {
- log_warn(LD_FS, "Cannot open fingerprint file '%s'. Failing.", fname);
- tor_free(fname);
- return -1;
- } else {
- log_info(LD_FS, "Cannot open fingerprint file '%s'. That's ok.", fname);
- tor_free(fname);
- return 0;
- }
+ log_warn(LD_FS, "Cannot open fingerprint file '%s'. That's ok.", fname);
+ tor_free(fname);
+ return 0;
}
tor_free(fname);
@@ -232,22 +195,8 @@ dirserv_load_fingerprint_file(void)
for (list=front; list; list=list->next) {
char digest_tmp[DIGEST_LEN];
+ router_status_t add_status = 0;
nickname = list->key; fingerprint = list->value;
- if (strlen(nickname) > MAX_NICKNAME_LEN) {
- log_notice(LD_CONFIG,
- "Nickname '%s' too long in fingerprint file. Skipping.",
- nickname);
- continue;
- }
- if (!is_legal_nickname(nickname) &&
- strcasecmp(nickname, "!reject") &&
- strcasecmp(nickname, "!invalid") &&
- strcasecmp(nickname, "!badexit")) {
- log_notice(LD_CONFIG,
- "Invalid nickname '%s' in fingerprint file. Skipping.",
- nickname);
- continue;
- }
tor_strstrip(fingerprint, " "); /* remove spaces */
if (strlen(fingerprint) != HEX_DIGEST_LEN ||
base16_decode(digest_tmp, sizeof(digest_tmp),
@@ -258,26 +207,14 @@ dirserv_load_fingerprint_file(void)
nickname, fingerprint);
continue;
}
- if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
- /* If you approved an OR called "client", then clients who use
- * the default nickname could all be rejected. That's no good. */
- log_notice(LD_CONFIG,
- "Authorizing nickname '%s' would break "
- "many clients; skipping.",
- DEFAULT_CLIENT_NICKNAME);
- continue;
- }
- if (0==strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME)) {
- /* If you approved an OR called "unnamed", then clients will be
- * confused. */
- log_notice(LD_CONFIG,
- "Authorizing nickname '%s' is not allowed; skipping.",
- UNNAMED_ROUTER_NICKNAME);
- continue;
+ if (!strcasecmp(nickname, "!reject")) {
+ add_status = FP_REJECT;
+ } else if (!strcasecmp(nickname, "!badexit")) {
+ add_status = FP_BADEXIT;
+ } else if (!strcasecmp(nickname, "!invalid")) {
+ add_status = FP_INVALID;
}
- if (add_fingerprint_to_dir(nickname, fingerprint, fingerprint_list_new)
- != 0)
- log_notice(LD_CONFIG, "Duplicate nickname '%s'.", nickname);
+ add_fingerprint_to_dir(fingerprint, fingerprint_list_new, add_status);
}
config_free_lines(front);
@@ -308,8 +245,7 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg)
return dirserv_get_status_impl(d, router->nickname,
router->addr, router->or_port,
- router->platform, router->contact_info,
- msg, 1);
+ router->platform, msg, 1);
}
/** Return true if there is no point in downloading the router described by
@@ -321,37 +257,14 @@ dirserv_would_reject_router(const routerstatus_t *rs)
res = dirserv_get_status_impl(rs->identity_digest, rs->nickname,
rs->addr, rs->or_port,
- NULL, NULL,
- NULL, 0);
+ NULL, NULL, 0);
return (res & FP_REJECT) != 0;
}
-/** Helper: Based only on the ID/Nickname combination,
- * return FP_UNNAMED (unnamed), FP_NAMED (named), or 0 (neither).
- */
-static uint32_t
-dirserv_get_name_status(const char *id_digest, const char *nickname)
-{
- char fp[HEX_DIGEST_LEN+1];
- char *fp_by_name;
-
- base16_encode(fp, sizeof(fp), id_digest, DIGEST_LEN);
-
- if ((fp_by_name =
- strmap_get_lc(fingerprint_list->fp_by_name, nickname))) {
- if (!strcasecmp(fp, fp_by_name)) {
- return FP_NAMED;
- } else {
- return FP_UNNAMED; /* Wrong fingerprint. */
- }
- }
- return 0;
-}
-
/** Helper: As dirserv_router_get_status, but takes the router fingerprint
* (hex, no spaces), nickname, address (used for logging only), IP address, OR
- * port, platform (logging only) and contact info (logging only) as arguments.
+ * port and platform (logging only) as arguments.
*
* If should_log is false, do not log messages. (There's not much point in
* logging that we're rejecting servers we'll not download.)
@@ -359,11 +272,9 @@ dirserv_get_name_status(const char *id_digest, const char *nickname)
static uint32_t
dirserv_get_status_impl(const char *id_digest, const char *nickname,
uint32_t addr, uint16_t or_port,
- const char *platform, const char *contact,
- const char **msg, int should_log)
+ const char *platform, const char **msg, int should_log)
{
- int reject_unlisted = get_options()->AuthDirRejectUnlisted;
- uint32_t result;
+ uint32_t result = 0;
router_status_t *status_by_digest;
if (!fingerprint_list)
@@ -381,43 +292,11 @@ dirserv_get_status_impl(const char *id_digest, const char *nickname,
*msg = "Tor version is insecure or unsupported. Please upgrade!";
return FP_REJECT;
}
-#if 0
- else if (platform && tor_version_as_new_as(platform,"0.2.3.0-alpha")) {
- /* Versions from 0.2.3-alpha...0.2.3.9-alpha have known security
- * issues that make them unusable for the current network */
- if (!tor_version_as_new_as(platform, "0.2.3.10-alpha")) {
- if (msg)
- *msg = "Tor version is insecure or unsupported. Please upgrade!";
- return FP_REJECT;
- }
- }
-#endif
-
- result = dirserv_get_name_status(id_digest, nickname);
- if (result & FP_NAMED) {
- if (should_log)
- log_debug(LD_DIRSERV,"Good fingerprint for '%s'",nickname);
- }
- if (result & FP_UNNAMED) {
- if (should_log) {
- char *esc_contact = esc_for_log(contact);
- log_info(LD_DIRSERV,
- "Mismatched fingerprint for '%s'. "
- "ContactInfo '%s', platform '%s'.)",
- nickname,
- esc_contact,
- platform ? escaped(platform) : "");
- tor_free(esc_contact);
- }
- if (msg)
- *msg = "Rejected: There is already a named server with this nickname "
- "and a different fingerprint.";
- }
status_by_digest = digestmap_get(fingerprint_list->status_by_digest,
id_digest);
if (status_by_digest)
- result |= (status_by_digest->status & ~FP_NAMED);
+ result |= *status_by_digest;
if (result & FP_REJECT) {
if (msg)
@@ -428,14 +307,6 @@ dirserv_get_status_impl(const char *id_digest, const char *nickname,
*msg = "Fingerprint is marked invalid";
}
- if (authdir_policy_baddir_address(addr, or_port)) {
- if (should_log)
- log_info(LD_DIRSERV,
- "Marking '%s' as bad directory because of address '%s'",
- nickname, fmt_addr32(addr));
- result |= FP_BADDIR;
- }
-
if (authdir_policy_badexit_address(addr, or_port)) {
if (should_log)
log_info(LD_DIRSERV, "Marking '%s' as bad exit because of address '%s'",
@@ -443,46 +314,24 @@ dirserv_get_status_impl(const char *id_digest, const char *nickname,
result |= FP_BADEXIT;
}
- if (!(result & FP_NAMED)) {
- if (!authdir_policy_permits_address(addr, or_port)) {
- if (should_log)
- log_info(LD_DIRSERV, "Rejecting '%s' because of address '%s'",
- nickname, fmt_addr32(addr));
- if (msg)
- *msg = "Authdir is rejecting routers in this range.";
- return FP_REJECT;
- }
- if (!authdir_policy_valid_address(addr, or_port)) {
- if (should_log)
- log_info(LD_DIRSERV, "Not marking '%s' valid because of address '%s'",
- nickname, fmt_addr32(addr));
- result |= FP_INVALID;
- }
- if (reject_unlisted) {
- if (msg)
- *msg = "Authdir rejects unknown routers.";
- return FP_REJECT;
- }
+ if (!authdir_policy_permits_address(addr, or_port)) {
+ if (should_log)
+ log_info(LD_DIRSERV, "Rejecting '%s' because of address '%s'",
+ nickname, fmt_addr32(addr));
+ if (msg)
+ *msg = "Authdir is rejecting routers in this range.";
+ return FP_REJECT;
+ }
+ if (!authdir_policy_valid_address(addr, or_port)) {
+ if (should_log)
+ log_info(LD_DIRSERV, "Not marking '%s' valid because of address '%s'",
+ nickname, fmt_addr32(addr));
+ result |= FP_INVALID;
}
return result;
}
-/** If we are an authoritative dirserver, and the list of approved
- * servers contains one whose identity key digest is <b>digest</b>,
- * return that router's nickname. Otherwise return NULL. */
-const char *
-dirserv_get_nickname_by_digest(const char *digest)
-{
- router_status_t *status;
- if (!fingerprint_list)
- return NULL;
- tor_assert(digest);
-
- status = digestmap_get(fingerprint_list->status_by_digest, digest);
- return status ? status->nickname : NULL;
-}
-
/** Clear the current fingerprint list. */
void
dirserv_free_fingerprint_list(void)
@@ -519,7 +368,7 @@ dirserv_router_has_valid_address(routerinfo_t *ri)
}
/** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
- * set its is_valid,named,running fields and return 0. Otherwise, return -1.
+ * set its is_valid,running fields and return 0. Otherwise, return -1.
*
* If the router is rejected, set *<b>msg</b> to an explanation of why.
*
@@ -584,7 +433,6 @@ dirserv_set_node_flags_from_authoritative_status(node_t *node,
uint32_t authstatus)
{
node->is_valid = (authstatus & FP_INVALID) ? 0 : 1;
- node->is_bad_directory = (authstatus & FP_BADDIR) ? 1 : 0;
node->is_bad_exit = (authstatus & FP_BADEXIT) ? 1 : 0;
}
@@ -816,7 +664,7 @@ directory_remove_invalid(void)
smartlist_add_all(nodes, nodelist_get_list());
SMARTLIST_FOREACH_BEGIN(nodes, node_t *, node) {
- const char *msg;
+ const char *msg = NULL;
routerinfo_t *ent = node->ri;
char description[NODE_DESC_BUF_LEN];
uint32_t r;
@@ -830,30 +678,11 @@ directory_remove_invalid(void)
routerlist_remove(rl, ent, 0, time(NULL));
continue;
}
-#if 0
- if (bool_neq((r & FP_NAMED), ent->auth_says_is_named)) {
- log_info(LD_DIRSERV,
- "Router %s is now %snamed.", description,
- (r&FP_NAMED)?"":"un");
- ent->is_named = (r&FP_NAMED)?1:0;
- }
- if (bool_neq((r & FP_UNNAMED), ent->auth_says_is_unnamed)) {
- log_info(LD_DIRSERV,
- "Router '%s' is now %snamed. (FP_UNNAMED)", description,
- (r&FP_NAMED)?"":"un");
- ent->is_named = (r&FP_NUNAMED)?0:1;
- }
-#endif
if (bool_neq((r & FP_INVALID), !node->is_valid)) {
log_info(LD_DIRSERV, "Router '%s' is now %svalid.", description,
(r&FP_INVALID) ? "in" : "");
node->is_valid = (r&FP_INVALID)?0:1;
}
- if (bool_neq((r & FP_BADDIR), node->is_bad_directory)) {
- log_info(LD_DIRSERV, "Router '%s' is now a %s directory", description,
- (r & FP_BADDIR) ? "bad" : "good");
- node->is_bad_directory = (r&FP_BADDIR) ? 1: 0;
- }
if (bool_neq((r & FP_BADEXIT), node->is_bad_exit)) {
log_info(LD_DIRSERV, "Router '%s' is now a %s exit", description,
(r & FP_BADEXIT) ? "bad" : "good");
@@ -1051,7 +880,8 @@ format_versions_list(config_line_t *ln)
}
/** Return 1 if <b>ri</b>'s descriptor is "active" -- running, valid,
- * not hibernating, and not too old. Else return 0.
+ * not hibernating, having observed bw greater 0, and not too old. Else
+ * return 0.
*/
static int
router_is_active(const routerinfo_t *ri, const node_t *node, time_t now)
@@ -1061,6 +891,8 @@ router_is_active(const routerinfo_t *ri, const node_t *node, time_t now)
return 0;
if (!node->is_running || !node->is_valid || ri->is_hibernating)
return 0;
+ if (!ri->bandwidthcapacity)
+ return 0;
return 1;
}
@@ -1468,7 +1300,7 @@ dirserv_thinks_router_is_hs_dir(const routerinfo_t *router,
* to fix the bug was 0.2.2.25-alpha. */
return (router->wants_to_be_hs_dir && router->dir_port &&
uptime >= get_options()->MinUptimeHidServDirectoryV2 &&
- node->is_running);
+ router_is_active(router, node, now));
}
/** Don't consider routers with less bandwidth than this when computing
@@ -1537,18 +1369,18 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
* sort them and use that to compute thresholds. */
n_active = n_active_nonexit = 0;
/* Uptime for every active router. */
- uptimes = tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
+ uptimes = tor_calloc(sizeof(uint32_t), smartlist_len(rl->routers));
/* Bandwidth for every active router. */
- bandwidths_kb = tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
+ bandwidths_kb = tor_calloc(sizeof(uint32_t), smartlist_len(rl->routers));
/* Bandwidth for every active non-exit router. */
bandwidths_excluding_exits_kb =
- tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
+ tor_calloc(sizeof(uint32_t), smartlist_len(rl->routers));
/* Weighted mean time between failure for each active router. */
- mtbfs = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
+ mtbfs = tor_calloc(sizeof(double), smartlist_len(rl->routers));
/* Time-known for each active router. */
- tks = tor_malloc(sizeof(long)*smartlist_len(rl->routers));
+ tks = tor_calloc(sizeof(long), smartlist_len(rl->routers));
/* Weighted fractional uptime for each active router. */
- wfus = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
+ wfus = tor_calloc(sizeof(double), smartlist_len(rl->routers));
nodelist_assert_ok();
@@ -1563,6 +1395,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
routerinfo_t *ri = node->ri;
const char *id = node->identity;
uint32_t bw_kb;
+ /* resolve spurious clang shallow analysis null pointer errors */
+ tor_assert(ri);
node->is_exit = (!router_exit_policy_rejects_all(ri) &&
exit_policy_is_general_exit(ri->exit_policy));
uptimes[n_active] = (uint32_t)real_uptime(ri, now);
@@ -1588,7 +1422,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
/* (Now bandwidths is sorted.) */
if (fast_bandwidth_kb < ROUTER_REQUIRED_MIN_BANDWIDTH/(2 * 1000))
fast_bandwidth_kb = bandwidths_kb[n_active/4];
- guard_bandwidth_including_exits_kb = bandwidths_kb[n_active*3/4];
+ guard_bandwidth_including_exits_kb =
+ third_quartile_uint32(bandwidths_kb, n_active);
guard_tk = find_nth_long(tks, n_active, n_active/8);
}
@@ -1959,13 +1794,12 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
char published[ISO_TIME_LEN+1];
char identity64[BASE64_DIGEST_LEN+1];
char digest64[BASE64_DIGEST_LEN+1];
- smartlist_t *chunks = NULL;
+ smartlist_t *chunks = smartlist_new();
format_iso_time(published, rs->published_on);
digest_to_base64(identity64, rs->identity_digest);
digest_to_base64(digest64, rs->descriptor_digest);
- chunks = smartlist_new();
smartlist_add_asprintf(chunks,
"r %s %s %s%s%s %s %d %d\n",
rs->nickname,
@@ -1996,19 +1830,16 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
goto done;
smartlist_add_asprintf(chunks,
- "s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ "s%s%s%s%s%s%s%s%s%s%s\n",
/* These must stay in alphabetical order. */
rs->is_authority?" Authority":"",
- rs->is_bad_directory?" BadDirectory":"",
rs->is_bad_exit?" BadExit":"",
rs->is_exit?" Exit":"",
rs->is_fast?" Fast":"",
rs->is_possible_guard?" Guard":"",
rs->is_hs_dir?" HSDir":"",
- rs->is_named?" Named":"",
rs->is_flagged_running?" Running":"",
rs->is_stable?" Stable":"",
- rs->is_unnamed?" Unnamed":"",
(rs->dir_port!=0)?" V2Dir":"",
rs->is_valid?" Valid":"");
@@ -2090,10 +1921,8 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
result = smartlist_join_strings(chunks, "", 0, NULL);
err:
- if (chunks) {
- SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
- smartlist_free(chunks);
- }
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_free(chunks);
return result;
}
@@ -2269,8 +2098,7 @@ is_router_version_good_for_possible_guard(const char *platform)
}
/** Extract status information from <b>ri</b> and from other authority
- * functions and store it in <b>rs</b>>. If <b>naming</b>, consider setting
- * the named flag in <b>rs</b>.
+ * functions and store it in <b>rs</b>>.
*
* We assume that ri-\>is_running has already been set, e.g. by
* dirserv_set_router_is_running(ri, now);
@@ -2280,8 +2108,8 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
node_t *node,
routerinfo_t *ri,
time_t now,
- int naming, int listbadexits,
- int listbaddirs, int vote_on_hsdirs)
+ int listbadexits,
+ int vote_on_hsdirs)
{
const or_options_t *options = get_options();
uint32_t routerbw_kb = dirserv_get_credible_bandwidth_kb(ri);
@@ -2301,12 +2129,6 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
!dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
rs->is_flagged_running = node->is_running; /* computed above */
- if (naming) {
- uint32_t name_status = dirserv_get_name_status(
- node->identity, ri->nickname);
- rs->is_named = (naming && (name_status & FP_NAMED)) ? 1 : 0;
- rs->is_unnamed = (naming && (name_status & FP_UNNAMED)) ? 1 : 0;
- }
rs->is_valid = node->is_valid;
if (node->is_fast &&
@@ -2323,19 +2145,12 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
} else {
rs->is_possible_guard = 0;
}
- if (options->TestingTorNetwork &&
- routerset_contains_routerstatus(options->TestingDirAuthVoteGuard,
- rs, 0)) {
- rs->is_possible_guard = 1;
- }
- rs->is_bad_directory = listbaddirs && node->is_bad_directory;
rs->is_bad_exit = listbadexits && node->is_bad_exit;
node->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, node, now);
rs->is_hs_dir = vote_on_hsdirs && node->is_hs_dir;
- if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
- rs->is_named = rs->is_unnamed = 0;
+ rs->is_named = rs->is_unnamed = 0;
rs->published_on = ri->cache_info.published_on;
memcpy(rs->identity_digest, node->identity, DIGEST_LEN);
@@ -2353,6 +2168,14 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
tor_addr_copy(&rs->ipv6_addr, &ri->ipv6_addr);
rs->ipv6_orport = ri->ipv6_orport;
}
+
+ /* Iff we are in a testing network, use TestingDirAuthVoteGuard to
+ give out Guard flags. */
+ if (options->TestingTorNetwork &&
+ routerset_contains_routerstatus(options->TestingDirAuthVoteGuard,
+ rs, 0)) {
+ rs->is_possible_guard = 1;
+ }
}
/** Routerstatus <b>rs</b> is part of a group of routers that are on
@@ -2364,8 +2187,7 @@ clear_status_flags_on_sybil(routerstatus_t *rs)
{
rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
rs->is_flagged_running = rs->is_named = rs->is_valid =
- rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit =
- rs->is_bad_directory = 0;
+ rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit = 0;
/* FFFF we might want some mechanism to check later on if we
* missed zeroing any flags: it's easy to add a new flag but
* forget to add it to this clause. */
@@ -2563,9 +2385,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
smartlist_t *routers, *routerstatuses;
char identity_digest[DIGEST_LEN];
char signing_key_digest[DIGEST_LEN];
- int naming = options->NamingAuthoritativeDir;
int listbadexits = options->AuthDirListBadExits;
- int listbaddirs = options->AuthDirListBadDirs;
int vote_on_hsdirs = options->VoteOnHidServDirectoriesV2;
routerlist_t *rl = router_get_routerlist();
time_t now = time(NULL);
@@ -2657,7 +2477,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
rs = &vrs->status;
set_routerstatus_from_routerinfo(rs, node, ri, now,
- naming, listbadexits, listbaddirs,
+ listbadexits,
vote_on_hsdirs);
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
@@ -2739,14 +2559,8 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
if (vote_on_reachability)
smartlist_add(v3_out->known_flags, tor_strdup("Running"));
- if (listbaddirs)
- smartlist_add(v3_out->known_flags, tor_strdup("BadDirectory"));
if (listbadexits)
smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
- if (naming) {
- smartlist_add(v3_out->known_flags, tor_strdup("Named"));
- smartlist_add(v3_out->known_flags, tor_strdup("Unnamed"));
- }
if (vote_on_hsdirs)
smartlist_add(v3_out->known_flags, tor_strdup("HSDir"));
smartlist_sort_strings(v3_out->known_flags);
diff --git a/src/or/dirserv.h b/src/or/dirserv.h
index 858e6e3a07..5d5ef2b732 100644
--- a/src/or/dirserv.h
+++ b/src/or/dirserv.h
@@ -34,10 +34,9 @@
int connection_dirserv_flushed_some(dir_connection_t *conn);
-int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_t *pk);
+int dirserv_add_own_fingerprint(crypto_pk_t *pk);
int dirserv_load_fingerprint_file(void);
void dirserv_free_fingerprint_list(void);
-const char *dirserv_get_nickname_by_digest(const char *digest);
enum was_router_added_t dirserv_add_multiple_descriptors(
const char *desc, uint8_t purpose,
const char *source,
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 137d6c1a8c..8a0fdf62fc 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -64,7 +64,7 @@ STATIC char *
format_networkstatus_vote(crypto_pk_t *private_signing_key,
networkstatus_t *v3_ns)
{
- smartlist_t *chunks;
+ smartlist_t *chunks = smartlist_new();
const char *client_versions = NULL, *server_versions = NULL;
char fingerprint[FINGERPRINT_LEN+1];
char digest[DIGEST_LEN];
@@ -98,7 +98,6 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
server_versions_line = tor_strdup("");
}
- chunks = smartlist_new();
{
char published[ISO_TIME_LEN+1];
char va[ISO_TIME_LEN+1];
@@ -110,7 +109,8 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
char *params;
authority_cert_t *cert = v3_ns->cert;
char *methods =
- make_consensus_method_list(1, MAX_SUPPORTED_CONSENSUS_METHOD, " ");
+ make_consensus_method_list(MIN_SUPPORTED_CONSENSUS_METHOD,
+ MAX_SUPPORTED_CONSENSUS_METHOD, " ");
format_iso_time(published, v3_ns->published);
format_iso_time(va, v3_ns->valid_after);
format_iso_time(fu, v3_ns->fresh_until);
@@ -230,10 +230,9 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
done:
tor_free(client_versions_line);
tor_free(server_versions_line);
- if (chunks) {
- SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
- smartlist_free(chunks);
- }
+
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_free(chunks);
return status;
}
@@ -458,8 +457,7 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
smartlist_free(alt_orports);
}
- if (consensus_method >= MIN_METHOD_FOR_MICRODESC &&
- microdesc_digest256_out) {
+ if (microdesc_digest256_out) {
smartlist_t *digests = smartlist_new();
const char *best_microdesc_digest;
SMARTLIST_FOREACH_BEGIN(votes, vote_routerstatus_t *, rs) {
@@ -541,7 +539,8 @@ compute_consensus_method(smartlist_t *votes)
static int
consensus_method_is_supported(int method)
{
- return (method >= 1) && (method <= MAX_SUPPORTED_CONSENSUS_METHOD);
+ return (method >= MIN_SUPPORTED_CONSENSUS_METHOD) &&
+ (method <= MAX_SUPPORTED_CONSENSUS_METHOD);
}
/** Return a newly allocated string holding the numbers between low and high
@@ -605,13 +604,14 @@ dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
const int n_votes = smartlist_len(votes);
smartlist_t *output;
smartlist_t *param_list = smartlist_new();
+ (void) method;
/* We require that the parameter lists in the votes are well-formed: that
is, that their keywords are unique and sorted, and that their values are
between INT32_MIN and INT32_MAX inclusive. This should be guaranteed by
the parsing code. */
- vals = tor_malloc(sizeof(int)*n_votes);
+ vals = tor_calloc(sizeof(int), n_votes);
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
if (!v->net_params)
@@ -647,12 +647,13 @@ dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
next_param = NULL;
else
next_param = smartlist_get(param_list, param_sl_idx+1);
+ /* resolve spurious clang shallow analysis null pointer errors */
+ tor_assert(param);
if (!next_param || strncmp(next_param, param, cur_param_len)) {
/* We've reached the end of a series. */
/* Make sure enough authorities voted on this param, unless the
* the consensus method we use is too old for that. */
- if (method < MIN_METHOD_FOR_MAJORITY_PARAMS ||
- i > total_authorities/2 ||
+ if (i > total_authorities/2 ||
i >= MIN_VOTES_FOR_PARAM) {
int32_t median = median_int32(vals, i);
char *out_string = tor_malloc(64+cur_param_len);
@@ -1005,300 +1006,6 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G,
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
return 1;
}
-/**
- * This function computes the bandwidth weights for consensus method 9.
- *
- * It has been obsoleted in favor of consensus method 10.
- */
-static void
-networkstatus_compute_bw_weights_v9(smartlist_t *chunks, int64_t G, int64_t M,
- int64_t E, int64_t D, int64_t T,
- int64_t weight_scale)
-{
- int64_t Wgg = -1, Wgd = -1;
- int64_t Wmg = -1, Wme = -1, Wmd = -1;
- int64_t Wed = -1, Wee = -1;
- const char *casename;
-
- if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
- log_warn(LD_DIR, "Consensus with empty bandwidth: "
- "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
- " D="I64_FORMAT" T="I64_FORMAT,
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- return;
- }
-
- /*
- * Computed from cases in 3.4.3 of dir-spec.txt
- *
- * 1. Neither are scarce
- * 2. Both Guard and Exit are scarce
- * a. R+D <= S
- * b. R+D > S
- * 3. One of Guard or Exit is scarce
- * a. S+D < T/3
- * b. S+D >= T/3
- */
- if (3*E >= T && 3*G >= T) { // E >= T/3 && G >= T/3
- bw_weights_error_t berr = 0;
- /* Case 1: Neither are scarce.
- *
- * Attempt to ensure that we have a large amount of exit bandwidth
- * in the middle position.
- */
- casename = "Case 1 (Wme*E = Wmd*D)";
- Wgg = (weight_scale*(D+E+G+M))/(3*G);
- if (D==0) Wmd = 0;
- else Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
- Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
- Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
- Wgd = 0;
- Wmg = weight_scale - Wgg;
- Wed = weight_scale - Wmd;
-
- berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
- weight_scale, G, M, E, D, T, 10, 1);
-
- if (berr) {
- log_warn(LD_DIR, "Bw Weights error %d for case %s. "
- "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
- " D="I64_FORMAT" T="I64_FORMAT,
- berr, casename,
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- }
- } else if (3*E < T && 3*G < T) { // E < T/3 && G < T/3
- int64_t R = MIN(E, G);
- int64_t S = MAX(E, G);
- /*
- * Case 2: Both Guards and Exits are scarce
- * Balance D between E and G, depending upon
- * D capacity and scarcity.
- */
- if (R+D < S) { // Subcase a
- Wgg = weight_scale;
- Wee = weight_scale;
- Wmg = 0;
- Wme = 0;
- Wmd = 0;
- if (E < G) {
- casename = "Case 2a (E scarce)";
- Wed = weight_scale;
- Wgd = 0;
- } else { /* E >= G */
- casename = "Case 2a (G scarce)";
- Wed = 0;
- Wgd = weight_scale;
- }
- } else { // Subcase b: R+D > S
- bw_weights_error_t berr = 0;
- casename = "Case 2b (Wme*E == Wmd*D)";
- if (D != 0) {
- Wgg = weight_scale;
- Wgd = (weight_scale*(D + E - 2*G + M))/(3*D); // T/3 >= G (Ok)
- Wmd = (weight_scale*(D + E + G - 2*M))/(6*D); // T/3 >= M
- Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
- Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E); // 2E+M >= T/3
- Wmg = 0;
- Wed = weight_scale - Wgd - Wmd;
-
- berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
- weight_scale, G, M, E, D, T, 10, 1);
- }
-
- if (D == 0 || berr) { // Can happen if M > T/3
- casename = "Case 2b (E=G)";
- Wgg = weight_scale;
- Wee = weight_scale;
- Wmg = 0;
- Wme = 0;
- Wmd = 0;
- if (D == 0) Wgd = 0;
- else Wgd = (weight_scale*(D+E-G))/(2*D);
- Wed = weight_scale - Wgd;
- berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
- Wed, weight_scale, G, M, E, D, T, 10, 1);
- }
- if (berr != BW_WEIGHTS_NO_ERROR &&
- berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
- log_warn(LD_DIR, "Bw Weights error %d for case %s. "
- "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
- " D="I64_FORMAT" T="I64_FORMAT,
- berr, casename,
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- }
- }
- } else { // if (E < T/3 || G < T/3) {
- int64_t S = MIN(E, G);
- // Case 3: Exactly one of Guard or Exit is scarce
- if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) {
- log_warn(LD_BUG,
- "Bw-Weights Case 3 but with G="I64_FORMAT" M="
- I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- }
-
- if (3*(S+D) < T) { // Subcase a: S+D < T/3
- if (G < E) {
- casename = "Case 3a (G scarce)";
- Wgg = Wgd = weight_scale;
- Wmd = Wed = Wmg = 0;
- // Minor subcase, if E is more scarce than M,
- // keep its bandwidth in place.
- if (E < M) Wme = 0;
- else Wme = (weight_scale*(E-M))/(2*E);
- Wee = weight_scale-Wme;
- } else { // G >= E
- casename = "Case 3a (E scarce)";
- Wee = Wed = weight_scale;
- Wmd = Wgd = Wme = 0;
- // Minor subcase, if G is more scarce than M,
- // keep its bandwidth in place.
- if (G < M) Wmg = 0;
- else Wmg = (weight_scale*(G-M))/(2*G);
- Wgg = weight_scale-Wmg;
- }
- } else { // Subcase b: S+D >= T/3
- bw_weights_error_t berr = 0;
- // D != 0 because S+D >= T/3
- if (G < E) {
- casename = "Case 3b (G scarce, Wme*E == Wmd*D)";
- Wgd = (weight_scale*(D + E - 2*G + M))/(3*D);
- Wmd = (weight_scale*(D + E + G - 2*M))/(6*D);
- Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
- Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E);
- Wgg = weight_scale;
- Wmg = 0;
- Wed = weight_scale - Wgd - Wmd;
-
- berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
- Wed, weight_scale, G, M, E, D, T, 10, 1);
- } else { // G >= E
- casename = "Case 3b (E scarce, Wme*E == Wmd*D)";
- Wgg = (weight_scale*(D + E + G + M))/(3*G);
- Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
- Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
- Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
- Wgd = 0;
- Wmg = weight_scale - Wgg;
- Wed = weight_scale - Wmd;
-
- berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
- Wed, weight_scale, G, M, E, D, T, 10, 1);
- }
- if (berr) {
- log_warn(LD_DIR, "Bw Weights error %d for case %s. "
- "G="I64_FORMAT" M="I64_FORMAT
- " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
- berr, casename,
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- }
- }
- }
-
- /* We cast down the weights to 32 bit ints on the assumption that
- * weight_scale is ~= 10000. We need to ensure a rogue authority
- * doesn't break this assumption to rig our weights */
- tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
-
- if (Wgg < 0 || Wgg > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wgg="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wgg),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
-
- Wgg = MAX(MIN(Wgg, weight_scale), 0);
- }
- if (Wgd < 0 || Wgd > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wgd="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wgd),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- Wgd = MAX(MIN(Wgd, weight_scale), 0);
- }
- if (Wmg < 0 || Wmg > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wmg="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wmg),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- Wmg = MAX(MIN(Wmg, weight_scale), 0);
- }
- if (Wme < 0 || Wme > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wme="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wme),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- Wme = MAX(MIN(Wme, weight_scale), 0);
- }
- if (Wmd < 0 || Wmd > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wmd="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wmd),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- Wmd = MAX(MIN(Wmd, weight_scale), 0);
- }
- if (Wee < 0 || Wee > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wee="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wee),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- Wee = MAX(MIN(Wee, weight_scale), 0);
- }
- if (Wed < 0 || Wed > weight_scale) {
- log_warn(LD_DIR, "Bw %s: Wed="I64_FORMAT"! G="I64_FORMAT
- " M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename, I64_PRINTF_ARG(Wed),
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
- Wed = MAX(MIN(Wed, weight_scale), 0);
- }
-
- // Add consensus weight keywords
- smartlist_add(chunks, tor_strdup("bandwidth-weights "));
- /*
- * Provide Wgm=Wgg, Wmm=1, Wem=Wee, Weg=Wed. May later determine
- * that middle nodes need different bandwidth weights for dirport traffic,
- * or that weird exit policies need special weight, or that bridges
- * need special weight.
- *
- * NOTE: This list is sorted.
- */
- smartlist_add_asprintf(chunks,
- "Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
- "Wdb=%d "
- "Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
- "Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
- "Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
- (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale,
- (int)weight_scale,
- (int)weight_scale, (int)Wed, (int)Wee, (int)Wed, (int)Wee,
- (int)weight_scale, (int)Wgd, (int)Wgg, (int)Wgg,
- (int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale);
-
- log_notice(LD_CIRC, "Computed bandwidth weights for %s with v9: "
- "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
- " T="I64_FORMAT,
- casename,
- I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
- I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
-}
/** Given a list of vote networkstatus_t in <b>votes</b>, our public
* authority <b>identity_key</b>, our private authority <b>signing_key</b>,
@@ -1350,18 +1057,18 @@ networkstatus_compute_consensus(smartlist_t *votes,
log_warn(LD_DIR, "The other authorities will use consensus method %d, "
"which I don't support. Maybe I should upgrade!",
consensus_method);
- consensus_method = 1;
+ consensus_method = MAX_SUPPORTED_CONSENSUS_METHOD;
}
/* Compute medians of time-related things, and figure out how many
* routers we might need to talk about. */
{
int n_votes = smartlist_len(votes);
- time_t *va_times = tor_malloc(n_votes * sizeof(time_t));
- time_t *fu_times = tor_malloc(n_votes * sizeof(time_t));
- time_t *vu_times = tor_malloc(n_votes * sizeof(time_t));
- int *votesec_list = tor_malloc(n_votes * sizeof(int));
- int *distsec_list = tor_malloc(n_votes * sizeof(int));
+ time_t *va_times = tor_calloc(n_votes, sizeof(time_t));
+ time_t *fu_times = tor_calloc(n_votes, sizeof(time_t));
+ time_t *vu_times = tor_calloc(n_votes, sizeof(time_t));
+ int *votesec_list = tor_calloc(n_votes, sizeof(int));
+ int *distsec_list = tor_calloc(n_votes, sizeof(int));
int n_versioning_clients = 0, n_versioning_servers = 0;
smartlist_t *combined_client_versions = smartlist_new();
smartlist_t *combined_server_versions = smartlist_new();
@@ -1441,10 +1148,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
flavor == FLAV_NS ? "" : " ",
flavor == FLAV_NS ? "" : flavor_name);
- if (consensus_method >= 2) {
- smartlist_add_asprintf(chunks, "consensus-method %d\n",
- consensus_method);
- }
+ smartlist_add_asprintf(chunks, "consensus-method %d\n",
+ consensus_method);
smartlist_add_asprintf(chunks,
"valid-after %s\n"
@@ -1461,14 +1166,12 @@ networkstatus_compute_consensus(smartlist_t *votes,
tor_free(flaglist);
}
- if (consensus_method >= MIN_METHOD_FOR_PARAMS) {
- params = dirvote_compute_params(votes, consensus_method,
- total_authorities);
- if (params) {
- smartlist_add(chunks, tor_strdup("params "));
- smartlist_add(chunks, params);
- smartlist_add(chunks, tor_strdup("\n"));
- }
+ params = dirvote_compute_params(votes, consensus_method,
+ total_authorities);
+ if (params) {
+ smartlist_add(chunks, tor_strdup("params "));
+ smartlist_add(chunks, params);
+ smartlist_add(chunks, tor_strdup("\n"));
}
/* Sort the votes. */
@@ -1482,8 +1185,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
e->digest = get_voter(v)->identity_digest;
e->is_legacy = 0;
smartlist_add(dir_sources, e);
- if (consensus_method >= 3 &&
- !tor_digest_is_zero(get_voter(v)->legacy_id_digest)) {
+ if (!tor_digest_is_zero(get_voter(v)->legacy_id_digest)) {
dir_src_ent_t *e_legacy = tor_malloc_zero(sizeof(dir_src_ent_t));
e_legacy->v = v;
e_legacy->digest = get_voter(v)->legacy_id_digest;
@@ -1499,9 +1201,6 @@ networkstatus_compute_consensus(smartlist_t *votes,
networkstatus_t *v = e->v;
networkstatus_voter_info_t *voter = get_voter(v);
- if (e->is_legacy)
- tor_assert(consensus_method >= 2);
-
base16_encode(fingerprint, sizeof(fingerprint), e->digest, DIGEST_LEN);
base16_encode(votedigest, sizeof(votedigest), voter->vote_digest,
DIGEST_LEN);
@@ -1559,9 +1258,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_t *chosen_flags = smartlist_new();
smartlist_t *versions = smartlist_new();
smartlist_t *exitsummaries = smartlist_new();
- uint32_t *bandwidths_kb = tor_malloc(sizeof(uint32_t) *
+ uint32_t *bandwidths_kb = tor_calloc(sizeof(uint32_t),
smartlist_len(votes));
- uint32_t *measured_bws_kb = tor_malloc(sizeof(uint32_t) *
+ uint32_t *measured_bws_kb = tor_calloc(sizeof(uint32_t),
smartlist_len(votes));
int num_bandwidths;
int num_mbws;
@@ -1574,7 +1273,6 @@ networkstatus_compute_consensus(smartlist_t *votes,
* is the same flag as votes[j]->known_flags[b]. */
int *named_flag; /* Index of the flag "Named" for votes[j] */
int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */
- int chosen_named_idx;
int n_authorities_measuring_bandwidth;
strmap_t *name_to_id_map = strmap_new();
@@ -1583,16 +1281,15 @@ networkstatus_compute_consensus(smartlist_t *votes,
memset(conflict, 0, sizeof(conflict));
memset(unknown, 0xff, sizeof(conflict));
- index = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
- size = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
- n_voter_flags = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
- n_flag_voters = tor_malloc_zero(sizeof(int) * smartlist_len(flags));
- flag_map = tor_malloc_zero(sizeof(int*) * smartlist_len(votes));
- named_flag = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
- unnamed_flag = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
+ index = tor_calloc(sizeof(int), smartlist_len(votes));
+ size = tor_calloc(sizeof(int), smartlist_len(votes));
+ n_voter_flags = tor_calloc(sizeof(int), smartlist_len(votes));
+ n_flag_voters = tor_calloc(sizeof(int), smartlist_len(flags));
+ flag_map = tor_calloc(sizeof(int *), smartlist_len(votes));
+ named_flag = tor_calloc(sizeof(int), smartlist_len(votes));
+ unnamed_flag = tor_calloc(sizeof(int), smartlist_len(votes));
for (i = 0; i < smartlist_len(votes); ++i)
unnamed_flag[i] = named_flag[i] = -1;
- chosen_named_idx = smartlist_string_pos(flags, "Named");
/* Build the flag indexes. Note that no vote can have more than 64 members
* for known_flags, so no value will be greater than 63, so it's safe to
@@ -1601,8 +1298,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
* that they're actually set before doing U64_LITERAL(1) << index with
* them.*/
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
- flag_map[v_sl_idx] = tor_malloc_zero(
- sizeof(int)*smartlist_len(v->known_flags));
+ flag_map[v_sl_idx] = tor_calloc(sizeof(int),
+ smartlist_len(v->known_flags));
if (smartlist_len(v->known_flags) > MAX_KNOWN_FLAGS_IN_VOTE) {
log_warn(LD_BUG, "Somehow, a vote has %d entries in known_flags",
smartlist_len(v->known_flags));
@@ -1622,7 +1319,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
} SMARTLIST_FOREACH_END(v);
/* Named and Unnamed get treated specially */
- if (consensus_method >= 2) {
+ {
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
uint64_t nf;
if (named_flag[v_sl_idx]<0)
@@ -1682,7 +1379,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
);
/* Now go through all the votes */
- flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags));
+ flag_counts = tor_calloc(sizeof(int), smartlist_len(flags));
while (1) {
vote_routerstatus_t *rs;
routerstatus_t rs_out;
@@ -1791,10 +1488,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
}
- if (consensus_method == 1) {
- is_named = chosen_named_idx >= 0 &&
- (!naming_conflict && flag_counts[chosen_named_idx]);
- } else {
+ {
const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
if (!d) {
is_named = is_unnamed = 0;
@@ -1811,7 +1505,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (!strcmp(fl, "Named")) {
if (is_named)
smartlist_add(chosen_flags, (char*)fl);
- } else if (!strcmp(fl, "Unnamed") && consensus_method >= 2) {
+ } else if (!strcmp(fl, "Unnamed")) {
if (is_unnamed)
smartlist_add(chosen_flags, (char*)fl);
} else {
@@ -1831,7 +1525,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
/* Starting with consensus method 4 we do not list servers
* that are not running in a consensus. See Proposal 138 */
- if (consensus_method >= 4 && !is_running)
+ if (!is_running)
continue;
/* Pick the version. */
@@ -1843,11 +1537,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* Pick a bandwidth */
- if (consensus_method >= 6 && num_mbws > 2) {
+ if (num_mbws > 2) {
rs_out.has_bandwidth = 1;
rs_out.bw_is_unmeasured = 0;
rs_out.bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
- } else if (consensus_method >= 5 && num_bandwidths > 0) {
+ } else if (num_bandwidths > 0) {
rs_out.has_bandwidth = 1;
rs_out.bw_is_unmeasured = 1;
rs_out.bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
@@ -1861,11 +1555,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* Fix bug 2203: Do not count BadExit nodes as Exits for bw weights */
- if (consensus_method >= MIN_METHOD_TO_CUT_BADEXIT_WEIGHT) {
- is_exit = is_exit && !is_bad_exit;
- }
+ is_exit = is_exit && !is_bad_exit;
- if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ {
if (rs_out.has_bandwidth) {
T += rs_out.bandwidth_kb;
if (is_exit && is_guard)
@@ -1896,7 +1588,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
* the policy that was most often listed in votes, again breaking
* ties like in the previous case.
*/
- if (consensus_method >= 5) {
+ {
/* Okay, go through all the votes for this router. We prepared
* that list previously */
const char *chosen_exitsummary = NULL;
@@ -1967,7 +1659,6 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
if (flavor == FLAV_MICRODESC &&
- consensus_method >= MIN_METHOD_FOR_MANDATORY_MICRODESC &&
tor_digest256_is_zero(microdesc_digest)) {
/* With no microdescriptor digest, we omit the entry entirely. */
continue;
@@ -2033,13 +1724,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
tor_free(measured_bws_kb);
}
- if (consensus_method >= MIN_METHOD_FOR_FOOTER) {
- /* Starting with consensus method 9, we clearly mark the directory
- * footer region */
- smartlist_add(chunks, tor_strdup("directory-footer\n"));
- }
+ /* Mark the directory footer region */
+ smartlist_add(chunks, tor_strdup("directory-footer\n"));
- if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
+ {
int64_t weight_scale = BW_WEIGHT_SCALE;
char *bw_weight_param = NULL;
@@ -2072,13 +1760,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
}
- if (consensus_method < 10) {
- networkstatus_compute_bw_weights_v9(chunks, G, M, E, D, T, weight_scale);
- added_weights = 1;
- } else {
- added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
- T, weight_scale);
- }
+ added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
+ T, weight_scale);
}
/* Add a signature. */
@@ -2119,7 +1802,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
smartlist_add(chunks, signature);
- if (legacy_id_key_digest && legacy_signing_key && consensus_method >= 3) {
+ if (legacy_id_key_digest && legacy_signing_key) {
smartlist_add(chunks, tor_strdup("directory-signature "));
base16_encode(fingerprint, sizeof(fingerprint),
legacy_id_key_digest, DIGEST_LEN);
@@ -2155,7 +1838,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
goto done;
}
// Verify balancing parameters
- if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS && added_weights) {
+ if (added_weights) {
networkstatus_verify_bw_weights(c, consensus_method);
}
networkstatus_vote_free(c);
@@ -2279,8 +1962,11 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
if (!sig->good_signature && !sig->bad_signature) {
cert = authority_cert_get_by_digests(sig->identity_digest,
sig->signing_key_digest);
- if (cert)
- networkstatus_check_document_signature(target, sig, cert);
+ if (cert) {
+ /* Not checking the return value here, since we are going to look
+ * at the status of sig->good_signature in a moment. */
+ (void) networkstatus_check_document_signature(target, sig, cert);
+ }
}
/* If this signature is good, or we don't have any signature yet,
@@ -3664,7 +3350,7 @@ static const struct consensus_method_range_t {
int low;
int high;
} microdesc_consensus_methods[] = {
- {MIN_METHOD_FOR_MICRODESC, MIN_METHOD_FOR_A_LINES - 1},
+ {MIN_SUPPORTED_CONSENSUS_METHOD, MIN_METHOD_FOR_A_LINES - 1},
{MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1},
{MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1},
{MIN_METHOD_FOR_NTOR_KEY, MIN_METHOD_FOR_ID_HASH_IN_MD - 1},
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
index 4c57e43661..7fa4010cf8 100644
--- a/src/or/dirvote.h
+++ b/src/or/dirvote.h
@@ -21,28 +21,12 @@
/** Smallest allowable voting interval. */
#define MIN_VOTE_INTERVAL 300
+/** The lowest consensus method that we currently support. */
+#define MIN_SUPPORTED_CONSENSUS_METHOD 13
+
/** The highest consensus method that we currently support. */
#define MAX_SUPPORTED_CONSENSUS_METHOD 18
-/** Lowest consensus method that contains a 'directory-footer' marker */
-#define MIN_METHOD_FOR_FOOTER 9
-
-/** Lowest consensus method that contains bandwidth weights */
-#define MIN_METHOD_FOR_BW_WEIGHTS 9
-
-/** Lowest consensus method that contains consensus params */
-#define MIN_METHOD_FOR_PARAMS 7
-
-/** Lowest consensus method that generates microdescriptors */
-#define MIN_METHOD_FOR_MICRODESC 8
-
-/** Lowest consensus method that doesn't count bad exits as exits for weight */
-#define MIN_METHOD_TO_CUT_BADEXIT_WEIGHT 11
-
-/** Lowest consensus method that ensures a majority of authorities voted
- * for a param. */
-#define MIN_METHOD_FOR_MAJORITY_PARAMS 12
-
/** Lowest consensus method where microdesc consensuses omit any entry
* with no microdesc. */
#define MIN_METHOD_FOR_MANDATORY_MICRODESC 13
@@ -116,8 +100,8 @@ const cached_dir_t *dirvote_get_vote(const char *fp, int flags);
void set_routerstatus_from_routerinfo(routerstatus_t *rs,
node_t *node,
routerinfo_t *ri, time_t now,
- int naming, int listbadexits,
- int listbaddirs, int vote_on_hsdirs);
+ int listbadexits,
+ int vote_on_hsdirs);
networkstatus_t *
dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
authority_cert_t *cert);
diff --git a/src/or/dns.c b/src/or/dns.c
index a9c4318651..362b97033e 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -244,8 +244,8 @@ cached_resolve_hash(cached_resolve_t *a)
HT_PROTOTYPE(cache_map, cached_resolve_t, node, cached_resolve_hash,
cached_resolves_eq)
-HT_GENERATE(cache_map, cached_resolve_t, node, cached_resolve_hash,
- cached_resolves_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(cache_map, cached_resolve_t, node, cached_resolve_hash,
+ cached_resolves_eq, 0.6, tor_reallocarray_, tor_free_)
/** Initialize the DNS cache. */
static void
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 66b7201187..b1fd310f97 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -12,6 +12,8 @@
* circumvention).
**/
+#define ENTRYNODES_PRIVATE
+
#include "or.h"
#include "circpathbias.h"
#include "circuitbuild.h"
@@ -154,21 +156,41 @@ entry_guard_set_status(entry_guard_t *e, const node_t *node,
/** Return true iff enough time has passed since we last tried to connect
* to the unreachable guard <b>e</b> that we're willing to try again. */
-static int
-entry_is_time_to_retry(entry_guard_t *e, time_t now)
+STATIC int
+entry_is_time_to_retry(const entry_guard_t *e, time_t now)
{
- long diff;
+ struct guard_retry_period_s {
+ time_t period_duration;
+ time_t interval_during_period;
+ };
+
+ struct guard_retry_period_s periods[] = {
+ { 6*60*60, 60*60 }, /* For first 6 hrs., retry hourly; */
+ { 3*24*60*60, 4*60*60 }, /* Then retry every 4 hrs. until the
+ 3-day mark; */
+ { 7*24*60*60, 18*60*60 }, /* After 3 days, retry every 18 hours until
+ 1 week mark. */
+ { TIME_MAX, 36*60*60 } /* After 1 week, retry every 36 hours. */
+ };
+
+ time_t ith_deadline_for_retry;
+ time_t unreachable_for;
+ unsigned i;
+
if (e->last_attempted < e->unreachable_since)
return 1;
- diff = now - e->unreachable_since;
- if (diff < 6*60*60)
- return now > (e->last_attempted + 60*60);
- else if (diff < 3*24*60*60)
- return now > (e->last_attempted + 4*60*60);
- else if (diff < 7*24*60*60)
- return now > (e->last_attempted + 18*60*60);
- else
- return now > (e->last_attempted + 36*60*60);
+
+ unreachable_for = now - e->unreachable_since;
+
+ for (i = 0; i < ARRAY_LENGTH(periods); i++) {
+ if (unreachable_for <= periods[i].period_duration) {
+ ith_deadline_for_retry = e->last_attempted +
+ periods[i].interval_during_period;
+
+ return (now > ith_deadline_for_retry);
+ }
+ }
+ return 0;
}
/** Return the node corresponding to <b>e</b>, if <b>e</b> is
@@ -188,12 +210,17 @@ entry_is_time_to_retry(entry_guard_t *e, time_t now)
* If need_descriptor is true, only return the node if we currently have
* a descriptor (routerinfo or microdesc) for it.
*/
-static INLINE const node_t *
-entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity,
- int assume_reachable, int need_descriptor, const char **msg)
+STATIC const node_t *
+entry_is_live(const entry_guard_t *e, entry_is_live_flags_t flags,
+ const char **msg)
{
const node_t *node;
const or_options_t *options = get_options();
+ int need_uptime = (flags & ENTRY_NEED_UPTIME) != 0;
+ int need_capacity = (flags & ENTRY_NEED_CAPACITY) != 0;
+ const int assume_reachable = (flags & ENTRY_ASSUME_REACHABLE) != 0;
+ const int need_descriptor = (flags & ENTRY_NEED_DESCRIPTOR) != 0;
+
tor_assert(msg);
if (e->path_bias_disabled) {
@@ -255,12 +282,18 @@ num_live_entry_guards(int for_directory)
{
int n = 0;
const char *msg;
+ /* Set the entry node attributes we are interested in. */
+ entry_is_live_flags_t entry_flags = ENTRY_NEED_CAPACITY;
+ if (!for_directory) {
+ entry_flags |= ENTRY_NEED_DESCRIPTOR;
+ }
+
if (! entry_guards)
return 0;
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
if (for_directory && !entry->is_dir_cache)
continue;
- if (entry_is_live(entry, 0, 1, 0, !for_directory, &msg))
+ if (entry_is_live(entry, entry_flags, &msg))
++n;
} SMARTLIST_FOREACH_END(entry);
return n;
@@ -289,7 +322,7 @@ log_entry_guards(int severity)
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e)
{
const char *msg = NULL;
- if (entry_is_live(e, 0, 1, 0, 0, &msg))
+ if (entry_is_live(e, ENTRY_NEED_CAPACITY, &msg))
smartlist_add_asprintf(elements, "%s [%s] (up %s)",
e->nickname,
hex_str(e->identity, DIGEST_LEN),
@@ -350,7 +383,7 @@ control_event_guard_deferred(void)
* If <b>chosen</b> is defined, use that one, and if it's not
* already in our entry_guards list, put it at the *beginning*.
* Else, put the one we pick at the end of the list. */
-static const node_t *
+STATIC const node_t *
add_an_entry_guard(const node_t *chosen, int reset_status, int prepend,
int for_discovery, int for_directory)
{
@@ -437,7 +470,7 @@ add_an_entry_guard(const node_t *chosen, int reset_status, int prepend,
/** Choose how many entry guards or directory guards we'll use. If
* <b>for_directory</b> is true, we return how many directory guards to
* use; else we return how many entry guards to use. */
-static int
+STATIC int
decide_num_guards(const or_options_t *options, int for_directory)
{
if (for_directory) {
@@ -676,7 +709,7 @@ entry_guards_compute_status(const or_options_t *options, time_t now)
SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
const char *reason = digestmap_get(reasons, entry->identity);
const char *live_msg = "";
- const node_t *r = entry_is_live(entry, 0, 1, 0, 0, &live_msg);
+ const node_t *r = entry_is_live(entry, ENTRY_NEED_CAPACITY, &live_msg);
log_info(LD_CIRC, "Summary: Entry %s [%s] is %s, %s%s%s, and %s%s.",
entry->nickname,
hex_str(entry->identity, DIGEST_LEN),
@@ -794,7 +827,9 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
break;
if (e->made_contact) {
const char *msg;
- const node_t *r = entry_is_live(e, 0, 1, 1, 0, &msg);
+ const node_t *r = entry_is_live(e,
+ ENTRY_NEED_CAPACITY | ENTRY_ASSUME_REACHABLE,
+ &msg);
if (r && e->unreachable_since) {
refuse_conn = 1;
e->can_retry = 1;
@@ -847,7 +882,7 @@ update_node_guard_status(void)
/** Adjust the entry guards list so that it only contains entries from
* EntryNodes, adding new entries from EntryNodes to the list as needed. */
-static void
+STATIC void
entry_guards_set_from_config(const or_options_t *options)
{
smartlist_t *entry_nodes, *worse_entry_nodes, *entry_fps;
@@ -1007,47 +1042,61 @@ choose_random_dirguard(dirinfo_type_t type)
return choose_random_entry_impl(NULL, 1, type, NULL);
}
-/** Helper for choose_random{entry,dirguard}. */
-static const node_t *
-choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
- dirinfo_type_t dirinfo_type, int *n_options_out)
+/** Filter <b>all_entry_guards</b> for usable entry guards and put them
+ * in <b>live_entry_guards</b>. We filter based on whether the node is
+ * currently alive, and on whether it satisfies the restrictions
+ * imposed by the other arguments of this function.
+ *
+ * We don't place more guards than NumEntryGuards in <b>live_entry_guards</b>.
+ *
+ * If <b>chosen_exit</b> is set, it contains the exit node of this
+ * circuit. Make sure to not use it or its family as an entry guard.
+ *
+ * If <b>need_uptime</b> is set, we are looking for a stable entry guard.
+ * if <b>need_capacity</b> is set, we are looking for a fast entry guard.
+ *
+ * The rest of the arguments are the same as in choose_random_entry_impl().
+ *
+ * Return 1 if we should choose a guard right away. Return 0 if we
+ * should try to add more nodes to our list before deciding on a
+ * guard.
+ */
+STATIC int
+populate_live_entry_guards(smartlist_t *live_entry_guards,
+ const smartlist_t *all_entry_guards,
+ const node_t *chosen_exit,
+ dirinfo_type_t dirinfo_type,
+ int for_directory,
+ int need_uptime, int need_capacity)
{
const or_options_t *options = get_options();
- smartlist_t *live_entry_guards = smartlist_new();
- smartlist_t *exit_family = smartlist_new();
- const node_t *chosen_exit =
- state?build_state_get_exit_node(state) : NULL;
const node_t *node = NULL;
- int need_uptime = state ? state->need_uptime : 0;
- int need_capacity = state ? state->need_capacity : 0;
- int preferred_min, consider_exit_family = 0;
- int need_descriptor = !for_directory;
const int num_needed = decide_num_guards(options, for_directory);
+ smartlist_t *exit_family = smartlist_new();
+ int retval = 0;
+ entry_is_live_flags_t entry_flags = 0;
- if (n_options_out)
- *n_options_out = 0;
+ { /* Set the flags we want our entry node to have */
+ if (need_uptime) {
+ entry_flags |= ENTRY_NEED_UPTIME;
+ }
+ if (need_capacity) {
+ entry_flags |= ENTRY_NEED_CAPACITY;
+ }
+ if (!for_directory) {
+ entry_flags |= ENTRY_NEED_DESCRIPTOR;
+ }
+ }
+
+ tor_assert(all_entry_guards);
if (chosen_exit) {
nodelist_add_node_and_family(exit_family, chosen_exit);
- consider_exit_family = 1;
}
- if (!entry_guards)
- entry_guards = smartlist_new();
-
- if (should_add_entry_nodes)
- entry_guards_set_from_config(options);
-
- if (!entry_list_is_constrained(options) &&
- smartlist_len(entry_guards) < num_needed)
- pick_entry_guards(options, for_directory);
-
- retry:
- smartlist_clear(live_entry_guards);
- SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
+ SMARTLIST_FOREACH_BEGIN(all_entry_guards, const entry_guard_t *, entry) {
const char *msg;
- node = entry_is_live(entry, need_uptime, need_capacity, 0,
- need_descriptor, &msg);
+ node = entry_is_live(entry, entry_flags, &msg);
if (!node)
continue; /* down, no point */
if (for_directory) {
@@ -1056,39 +1105,94 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
}
if (node == chosen_exit)
continue; /* don't pick the same node for entry and exit */
- if (consider_exit_family && smartlist_contains(exit_family, node))
+ if (smartlist_contains(exit_family, node))
continue; /* avoid relays that are family members of our exit */
if (dirinfo_type != NO_DIRINFO &&
!node_can_handle_dirinfo(node, dirinfo_type))
continue; /* this node won't be able to answer our dir questions */
-#if 0 /* since EntryNodes is always strict now, this clause is moot */
- if (options->EntryNodes &&
- !routerset_contains_node(options->EntryNodes, node)) {
- /* We've come to the end of our preferred entry nodes. */
- if (smartlist_len(live_entry_guards))
- goto choose_and_finish; /* only choose from the ones we like */
- if (options->StrictNodes) {
- /* in theory this case should never happen, since
- * entry_guards_set_from_config() drops unwanted relays */
- tor_fragile_assert();
- } else {
- log_info(LD_CIRC,
- "No relays from EntryNodes available. Using others.");
- }
- }
-#endif
smartlist_add(live_entry_guards, (void*)node);
if (!entry->made_contact) {
/* Always start with the first not-yet-contacted entry
* guard. Otherwise we might add several new ones, pick
* the second new one, and now we've expanded our entry
* guard list without needing to. */
- goto choose_and_finish;
+ retval = 1;
+ goto done;
+ }
+ if (smartlist_len(live_entry_guards) >= num_needed) {
+ retval = 1;
+ goto done; /* We picked enough entry guards. Done! */
}
- if (smartlist_len(live_entry_guards) >= num_needed)
- goto choose_and_finish; /* we have enough */
} SMARTLIST_FOREACH_END(entry);
+ done:
+ smartlist_free(exit_family);
+
+ return retval;
+}
+
+/** Pick a node to be used as the entry guard of a circuit.
+ *
+ * If <b>state</b> is set, it contains the information we know about
+ * the upcoming circuit.
+ *
+ * If <b>for_directory</b> is set, we are looking for a directory guard.
+ *
+ * <b>dirinfo_type</b> contains the kind of directory information we
+ * are looking for in our node.
+ *
+ * If <b>n_options_out</b> is set, we set it to the number of
+ * candidate guard nodes we had before picking a specific guard node.
+ *
+ * On success, return the node that should be used as the entry guard
+ * of the circuit. Return NULL if no such node could be found.
+ *
+ * Helper for choose_random{entry,dirguard}.
+*/
+static const node_t *
+choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
+ dirinfo_type_t dirinfo_type, int *n_options_out)
+{
+ const or_options_t *options = get_options();
+ smartlist_t *live_entry_guards = smartlist_new();
+ const node_t *chosen_exit =
+ state?build_state_get_exit_node(state) : NULL;
+ const node_t *node = NULL;
+ int need_uptime = state ? state->need_uptime : 0;
+ int need_capacity = state ? state->need_capacity : 0;
+ int preferred_min = 0;
+ const int num_needed = decide_num_guards(options, for_directory);
+ int retval = 0;
+
+ if (n_options_out)
+ *n_options_out = 0;
+
+ if (!entry_guards)
+ entry_guards = smartlist_new();
+
+ if (should_add_entry_nodes)
+ entry_guards_set_from_config(options);
+
+ if (!entry_list_is_constrained(options) &&
+ smartlist_len(entry_guards) < num_needed)
+ pick_entry_guards(options, for_directory);
+
+ retry:
+ smartlist_clear(live_entry_guards);
+
+ /* Populate the list of live entry guards so that we pick one of
+ them. */
+ retval = populate_live_entry_guards(live_entry_guards,
+ entry_guards,
+ chosen_exit,
+ dirinfo_type,
+ for_directory,
+ need_uptime, need_capacity);
+
+ if (retval == 1) { /* We should choose a guard right now. */
+ goto choose_and_finish;
+ }
+
if (entry_list_is_constrained(options)) {
/* If we prefer the entry nodes we've got, and we have at least
* one choice, that's great. Use it. */
@@ -1127,18 +1231,7 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
need_capacity = 0;
goto retry;
}
-#if 0
- /* Removing this retry logic: if we only allow one exit, and it is in the
- same family as all our entries, then we are just plain not going to win
- here. */
- if (!node && entry_list_is_constrained(options) && consider_exit_family) {
- /* still no? if we're using bridges or have strictentrynodes
- * set, and our chosen exit is in the same family as all our
- * bridges/entry guards, then be flexible about families. */
- consider_exit_family = 0;
- goto retry;
- }
-#endif
+
/* live_entry_guards may be empty below. Oh well, we tried. */
}
@@ -1156,7 +1249,6 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
if (n_options_out)
*n_options_out = smartlist_len(live_entry_guards);
smartlist_free(live_entry_guards);
- smartlist_free(exit_family);
return node;
}
@@ -2199,6 +2291,13 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache)
node = node_get_mutable_by_id(ri->cache_info.identity_digest);
tor_assert(node);
rewrite_node_address_for_bridge(bridge, node);
+ if (tor_digest_is_zero(bridge->identity)) {
+ memcpy(bridge->identity,ri->cache_info.identity_digest, DIGEST_LEN);
+ log_notice(LD_DIR, "Learned identity %s for bridge at %s:%d",
+ hex_str(bridge->identity, DIGEST_LEN),
+ fmt_and_decorate_addr(&bridge->addr),
+ (int) bridge->port);
+ }
add_an_entry_guard(node, 1, 1, 0, 0);
log_notice(LD_DIR, "new bridge descriptor '%s' (%s): %s", ri->nickname,
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index e229f3b79a..52b31a225d 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -77,6 +77,38 @@ int num_live_entry_guards(int for_directory);
#endif
+#ifdef ENTRYNODES_PRIVATE
+STATIC const node_t *add_an_entry_guard(const node_t *chosen,
+ int reset_status, int prepend,
+ int for_discovery, int for_directory);
+
+STATIC int populate_live_entry_guards(smartlist_t *live_entry_guards,
+ const smartlist_t *all_entry_guards,
+ const node_t *chosen_exit,
+ dirinfo_type_t dirinfo_type,
+ int for_directory,
+ int need_uptime, int need_capacity);
+STATIC int decide_num_guards(const or_options_t *options, int for_directory);
+
+STATIC void entry_guards_set_from_config(const or_options_t *options);
+
+/** Flags to be passed to entry_is_live() to indicate what kind of
+ * entry nodes we are looking for. */
+typedef enum {
+ ENTRY_NEED_UPTIME = 1<<0,
+ ENTRY_NEED_CAPACITY = 1<<1,
+ ENTRY_ASSUME_REACHABLE = 1<<2,
+ ENTRY_NEED_DESCRIPTOR = 1<<3,
+} entry_is_live_flags_t;
+
+STATIC const node_t *entry_is_live(const entry_guard_t *e,
+ entry_is_live_flags_t flags,
+ const char **msg);
+
+STATIC int entry_is_time_to_retry(const entry_guard_t *e, time_t now);
+
+#endif
+
void remove_all_entry_guards(void);
void entry_guards_compute_status(const or_options_t *options, time_t now);
diff --git a/src/or/fp_pair.c b/src/or/fp_pair.c
index 55e4c89a42..1be169609a 100644
--- a/src/or/fp_pair.c
+++ b/src/or/fp_pair.c
@@ -42,9 +42,9 @@ fp_pair_map_entry_hash(const fp_pair_map_entry_t *a)
HT_PROTOTYPE(fp_pair_map_impl, fp_pair_map_entry_s, node,
fp_pair_map_entry_hash, fp_pair_map_entries_eq)
-HT_GENERATE(fp_pair_map_impl, fp_pair_map_entry_s, node,
- fp_pair_map_entry_hash, fp_pair_map_entries_eq,
- 0.6, tor_malloc, tor_realloc, tor_free)
+HT_GENERATE2(fp_pair_map_impl, fp_pair_map_entry_s, node,
+ fp_pair_map_entry_hash, fp_pair_map_entries_eq,
+ 0.6, tor_reallocarray_, tor_free_)
/** Constructor to create a new empty map from fp_pair_t to void *
*/
diff --git a/src/or/geoip.c b/src/or/geoip.c
index f722bac468..cdf2797db0 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -58,8 +58,8 @@ static char geoip6_digest[DIGEST_LEN];
/** Return the index of the <b>country</b>'s entry in the GeoIP
* country list if it is a valid 2-letter country code, otherwise
* return -1. */
-country_t
-geoip_get_country(const char *country)
+MOCK_IMPL(country_t,
+geoip_get_country,(const char *country))
{
void *idxplus1_;
intptr_t idx;
@@ -396,8 +396,8 @@ geoip_get_country_by_ipv6(const struct in6_addr *addr)
* the 'unknown country'. The return value will always be less than
* geoip_get_n_countries(). To decode it, call geoip_get_country_name().
*/
-int
-geoip_get_country_by_addr(const tor_addr_t *addr)
+MOCK_IMPL(int,
+geoip_get_country_by_addr,(const tor_addr_t *addr))
{
if (tor_addr_family(addr) == AF_INET) {
return geoip_get_country_by_ipv4(tor_addr_to_ipv4h(addr));
@@ -409,8 +409,8 @@ geoip_get_country_by_addr(const tor_addr_t *addr)
}
/** Return the number of countries recognized by the GeoIP country list. */
-int
-geoip_get_n_countries(void)
+MOCK_IMPL(int,
+geoip_get_n_countries,(void))
{
if (!geoip_countries)
init_geoip_countries();
@@ -430,8 +430,8 @@ geoip_get_country_name(country_t num)
}
/** Return true iff we have loaded a GeoIP database.*/
-int
-geoip_is_loaded(sa_family_t family)
+MOCK_IMPL(int,
+geoip_is_loaded,(sa_family_t family))
{
tor_assert(family == AF_INET || family == AF_INET6);
if (geoip_countries == NULL)
@@ -506,8 +506,8 @@ clientmap_entries_eq(const clientmap_entry_t *a, const clientmap_entry_t *b)
HT_PROTOTYPE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
clientmap_entries_eq);
-HT_GENERATE(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
- clientmap_entries_eq, 0.6, malloc, realloc, free);
+HT_GENERATE2(clientmap, clientmap_entry_t, node, clientmap_entry_hash,
+ clientmap_entries_eq, 0.6, tor_reallocarray_, tor_free_)
/** Free all storage held by <b>ent</b>. */
static void
@@ -720,8 +720,8 @@ dirreq_map_ent_hash(const dirreq_map_entry_t *entry)
HT_PROTOTYPE(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
dirreq_map_ent_eq);
-HT_GENERATE(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
- dirreq_map_ent_eq, 0.6, malloc, realloc, free);
+HT_GENERATE2(dirreqmap, dirreq_map_entry_t, node, dirreq_map_ent_hash,
+ dirreq_map_ent_eq, 0.6, tor_reallocarray_, tor_free_)
/** Helper: Put <b>entry</b> into map of directory requests using
* <b>type</b> and <b>dirreq_id</b> as key parts. If there is
@@ -963,7 +963,7 @@ geoip_get_dirreq_history(dirreq_type_t type)
/* We may have rounded 'completed' up. Here we want to use the
* real value. */
complete = smartlist_len(dirreq_completed);
- dltimes = tor_malloc_zero(sizeof(uint32_t) * complete);
+ dltimes = tor_calloc(sizeof(uint32_t), complete);
SMARTLIST_FOREACH_BEGIN(dirreq_completed, dirreq_map_entry_t *, ent) {
uint32_t bytes_per_second;
uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time,
@@ -1033,7 +1033,7 @@ geoip_get_client_history(geoip_client_action_t action,
if (!geoip_is_loaded(AF_INET) && !geoip_is_loaded(AF_INET6))
return -1;
- counts = tor_malloc_zero(sizeof(unsigned)*n_countries);
+ counts = tor_calloc(sizeof(unsigned), n_countries);
HT_FOREACH(ent, clientmap, &client_history) {
int country;
if ((*ent)->action != (int)action)
diff --git a/src/or/geoip.h b/src/or/geoip.h
index b9b53c3006..f702617d9c 100644
--- a/src/or/geoip.h
+++ b/src/or/geoip.h
@@ -21,12 +21,12 @@ STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr);
#endif
int should_record_bridge_info(const or_options_t *options);
int geoip_load_file(sa_family_t family, const char *filename);
-int geoip_get_country_by_addr(const tor_addr_t *addr);
-int geoip_get_n_countries(void);
+MOCK_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr));
+MOCK_DECL(int, geoip_get_n_countries, (void));
const char *geoip_get_country_name(country_t num);
-int geoip_is_loaded(sa_family_t family);
+MOCK_DECL(int, geoip_is_loaded, (sa_family_t family));
const char *geoip_db_digest(sa_family_t family);
-country_t geoip_get_country(const char *countrycode);
+MOCK_DECL(country_t, geoip_get_country, (const char *countrycode));
void geoip_note_client_seen(geoip_client_action_t action,
const tor_addr_t *addr, const char *transport_name,
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index c433ac1be9..b3761cfabf 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -410,6 +410,17 @@ configure_accounting(time_t now)
accounting_set_wakeup_time();
}
+/** Return the relevant number of bytes sent/received this interval
+ * based on the set AccountingRule */
+static uint64_t
+get_accounting_bytes(void)
+{
+ if (get_options()->AccountingRule == ACCT_SUM)
+ return n_bytes_read_in_interval+n_bytes_written_in_interval;
+ else
+ return MAX(n_bytes_read_in_interval, n_bytes_written_in_interval);
+}
+
/** Set expected_bandwidth_usage based on how much we sent/received
* per minute last interval (if we were up for at least 30 minutes),
* or based on our declared bandwidth otherwise. */
@@ -421,6 +432,11 @@ update_expected_bandwidth(void)
uint64_t max_configured = (options->RelayBandwidthRate > 0 ?
options->RelayBandwidthRate :
options->BandwidthRate) * 60;
+ /* max_configured is the larger of bytes read and bytes written
+ * If we are accounting based on sum, worst case is both are
+ * at max, doubling the expected sum of bandwidth */
+ if (get_options()->AccountingRule == ACCT_SUM)
+ max_configured *= 2;
#define MIN_TIME_FOR_MEASUREMENT (1800)
@@ -439,8 +455,7 @@ update_expected_bandwidth(void)
* doesn't know to store soft-limit info. Just take rate at which
* we were reading/writing in the last interval as our expected rate.
*/
- uint64_t used = MAX(n_bytes_written_in_interval,
- n_bytes_read_in_interval);
+ uint64_t used = get_accounting_bytes();
expected = used / (n_seconds_active_in_interval / 60);
} else {
/* If we haven't gotten enough data last interval, set 'expected'
@@ -715,8 +730,7 @@ hibernate_hard_limit_reached(void)
uint64_t hard_limit = get_options()->AccountingMax;
if (!hard_limit)
return 0;
- return n_bytes_read_in_interval >= hard_limit
- || n_bytes_written_in_interval >= hard_limit;
+ return get_accounting_bytes() >= hard_limit;
}
/** Return true iff we have sent/received almost all the bytes we are willing
@@ -747,8 +761,7 @@ hibernate_soft_limit_reached(void)
if (!soft_limit)
return 0;
- return n_bytes_read_in_interval >= soft_limit
- || n_bytes_written_in_interval >= soft_limit;
+ return get_accounting_bytes() >= soft_limit;
}
/** Called when we get a SIGINT, or when bandwidth soft limit is
@@ -772,8 +785,7 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
hibernate_state == HIBERNATE_STATE_LIVE) {
soft_limit_hit_at = now;
n_seconds_to_hit_soft_limit = n_seconds_active_in_interval;
- n_bytes_at_soft_limit = MAX(n_bytes_read_in_interval,
- n_bytes_written_in_interval);
+ n_bytes_at_soft_limit = get_accounting_bytes();
}
/* close listeners. leave control listener(s). */
@@ -1003,13 +1015,22 @@ getinfo_helper_accounting(control_connection_t *conn,
U64_PRINTF_ARG(n_bytes_written_in_interval));
} else if (!strcmp(question, "accounting/bytes-left")) {
uint64_t limit = get_options()->AccountingMax;
- uint64_t read_left = 0, write_left = 0;
- if (n_bytes_read_in_interval < limit)
- read_left = limit - n_bytes_read_in_interval;
- if (n_bytes_written_in_interval < limit)
- write_left = limit - n_bytes_written_in_interval;
- tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
- U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left));
+ if (get_options()->AccountingRule == ACCT_SUM) {
+ uint64_t total_left = 0;
+ uint64_t total_bytes = get_accounting_bytes();
+ if (total_bytes < limit)
+ total_left = limit - total_bytes;
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
+ U64_PRINTF_ARG(total_left), U64_PRINTF_ARG(total_left));
+ } else {
+ uint64_t read_left = 0, write_left = 0;
+ if (n_bytes_read_in_interval < limit)
+ read_left = limit - n_bytes_read_in_interval;
+ if (n_bytes_written_in_interval < limit)
+ write_left = limit - n_bytes_written_in_interval;
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
+ U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left));
+ }
} else if (!strcmp(question, "accounting/interval-start")) {
*answer = tor_malloc(ISO_TIME_LEN+1);
format_iso_time(*answer, interval_start_time);
diff --git a/src/or/hibernate.h b/src/or/hibernate.h
index 38ecb75129..799b582543 100644
--- a/src/or/hibernate.h
+++ b/src/or/hibernate.h
@@ -28,6 +28,7 @@ void consider_hibernation(time_t now);
int getinfo_helper_accounting(control_connection_t *conn,
const char *question, char **answer,
const char **errmsg);
+uint64_t get_accounting_max_total(void);
#ifdef HIBERNATE_PRIVATE
/** Possible values of hibernate_state */
diff --git a/src/or/main.c b/src/or/main.c
index 9c1cabf037..61efc1f6f2 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -28,6 +28,7 @@
#include "connection_or.h"
#include "control.h"
#include "cpuworker.h"
+#include "crypto_s2k.h"
#include "directory.h"
#include "dirserv.h"
#include "dirvote.h"
@@ -1861,6 +1862,10 @@ do_hup(void)
return -1;
}
options = get_options(); /* they have changed now */
+ /* Logs are only truncated the first time they are opened, but were
+ probably intended to be cleaned up on signal. */
+ if (options->TruncateLogFile)
+ truncate_logs();
} else {
char *msg = NULL;
log_notice(LD_GENERAL, "Not reloading config file: the controller told "
@@ -2670,11 +2675,11 @@ do_hash_password(void)
{
char output[256];
- char key[S2K_SPECIFIER_LEN+DIGEST_LEN];
+ char key[S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN];
- crypto_rand(key, S2K_SPECIFIER_LEN-1);
- key[S2K_SPECIFIER_LEN-1] = (uint8_t)96; /* Hash 64 K of data. */
- secret_to_key(key+S2K_SPECIFIER_LEN, DIGEST_LEN,
+ crypto_rand(key, S2K_RFC2440_SPECIFIER_LEN-1);
+ key[S2K_RFC2440_SPECIFIER_LEN-1] = (uint8_t)96; /* Hash 64 K of data. */
+ secret_to_key_rfc2440(key+S2K_RFC2440_SPECIFIER_LEN, DIGEST_LEN,
get_options()->command_arg, strlen(get_options()->command_arg),
key);
base16_encode(output, sizeof(output), key, sizeof(key));
@@ -2709,31 +2714,6 @@ do_dump_config(void)
return 0;
}
-#if defined (WINCE)
-int
-find_flashcard_path(PWCHAR path, size_t size)
-{
- WIN32_FIND_DATA d = {0};
- HANDLE h = NULL;
-
- if (!path)
- return -1;
-
- h = FindFirstFlashCard(&d);
- if (h == INVALID_HANDLE_VALUE)
- return -1;
-
- if (wcslen(d.cFileName) == 0) {
- FindClose(h);
- return -1;
- }
-
- wcsncpy(path,d.cFileName,size);
- FindClose(h);
- return 0;
-}
-#endif
-
static void
init_addrinfo(void)
{
@@ -2754,43 +2734,47 @@ sandbox_init_filter(void)
sandbox_cfg_allow_openat_filename(&cfg,
get_datadir_fname("cached-status"));
- sandbox_cfg_allow_open_filename_array(&cfg,
- get_datadir_fname("cached-certs"),
- get_datadir_fname("cached-certs.tmp"),
- get_datadir_fname("cached-consensus"),
- get_datadir_fname("cached-consensus.tmp"),
- get_datadir_fname("unverified-consensus"),
- get_datadir_fname("unverified-consensus.tmp"),
- get_datadir_fname("unverified-microdesc-consensus"),
- get_datadir_fname("unverified-microdesc-consensus.tmp"),
- get_datadir_fname("cached-microdesc-consensus"),
- get_datadir_fname("cached-microdesc-consensus.tmp"),
- get_datadir_fname("cached-microdescs"),
- get_datadir_fname("cached-microdescs.tmp"),
- get_datadir_fname("cached-microdescs.new"),
- get_datadir_fname("cached-microdescs.new.tmp"),
- get_datadir_fname("cached-descriptors"),
- get_datadir_fname("cached-descriptors.new"),
- get_datadir_fname("cached-descriptors.tmp"),
- get_datadir_fname("cached-descriptors.new.tmp"),
- get_datadir_fname("cached-descriptors.tmp.tmp"),
- get_datadir_fname("cached-extrainfo"),
- get_datadir_fname("cached-extrainfo.new"),
- get_datadir_fname("cached-extrainfo.tmp"),
- get_datadir_fname("cached-extrainfo.new.tmp"),
- get_datadir_fname("cached-extrainfo.tmp.tmp"),
- get_datadir_fname("state.tmp"),
- get_datadir_fname("unparseable-desc.tmp"),
- get_datadir_fname("unparseable-desc"),
- get_datadir_fname("v3-status-votes"),
- get_datadir_fname("v3-status-votes.tmp"),
- tor_strdup("/dev/srandom"),
- tor_strdup("/dev/urandom"),
- tor_strdup("/dev/random"),
- tor_strdup("/etc/hosts"),
- tor_strdup("/proc/meminfo"),
- NULL, 0
- );
+#define OPEN(name) \
+ sandbox_cfg_allow_open_filename(&cfg, tor_strdup(name))
+
+#define OPEN_DATADIR(name) \
+ sandbox_cfg_allow_open_filename(&cfg, get_datadir_fname(name))
+
+#define OPEN_DATADIR2(name, name2) \
+ sandbox_cfg_allow_open_filename(&cfg, get_datadir_fname2((name), (name2)))
+
+#define OPEN_DATADIR_SUFFIX(name, suffix) do { \
+ OPEN_DATADIR(name); \
+ OPEN_DATADIR(name suffix); \
+ } while (0)
+
+#define OPEN_DATADIR2_SUFFIX(name, name2, suffix) do { \
+ OPEN_DATADIR2(name, name2); \
+ OPEN_DATADIR2(name, name2 suffix); \
+ } while (0)
+
+ OPEN_DATADIR_SUFFIX("cached-certs", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-consensus", ".tmp");
+ OPEN_DATADIR_SUFFIX("unverified-consensus", ".tmp");
+ OPEN_DATADIR_SUFFIX("unverified-microdesc-consensus", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-microdesc-consensus", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-microdescs", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-microdescs.new", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-descriptors", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-descriptors.new", ".tmp");
+ OPEN_DATADIR("cached-descriptors.tmp.tmp");
+ OPEN_DATADIR_SUFFIX("cached-extrainfo", ".tmp");
+ OPEN_DATADIR_SUFFIX("cached-extrainfo.new", ".tmp");
+ OPEN_DATADIR("cached-extrainfo.tmp.tmp");
+ OPEN_DATADIR_SUFFIX("state", ".tmp");
+ OPEN_DATADIR_SUFFIX("unparseable-desc", ".tmp");
+ OPEN_DATADIR_SUFFIX("v3-status-votes", ".tmp");
+ OPEN("/dev/srandom");
+ OPEN("/dev/urandom");
+ OPEN("/dev/random");
+ OPEN("/etc/hosts");
+ OPEN("/proc/meminfo");
+
if (options->ServerDNSResolvConfFile)
sandbox_cfg_allow_open_filename(&cfg,
tor_strdup(options->ServerDNSResolvConfFile));
@@ -2831,14 +2815,17 @@ sandbox_init_filter(void)
RENAME_SUFFIX("unparseable-desc", ".tmp");
RENAME_SUFFIX("v3-status-votes", ".tmp");
- sandbox_cfg_allow_stat_filename_array(&cfg,
- get_datadir_fname(NULL),
- get_datadir_fname("lock"),
- get_datadir_fname("state"),
- get_datadir_fname("router-stability"),
- get_datadir_fname("cached-extrainfo.new"),
- NULL, 0
- );
+#define STAT_DATADIR(name) \
+ sandbox_cfg_allow_stat_filename(&cfg, get_datadir_fname(name))
+
+#define STAT_DATADIR2(name, name2) \
+ sandbox_cfg_allow_stat_filename(&cfg, get_datadir_fname2((name), (name2)))
+
+ STAT_DATADIR(NULL);
+ STAT_DATADIR("lock");
+ STAT_DATADIR("state");
+ STAT_DATADIR("router-stability");
+ STAT_DATADIR("cached-extrainfo.new");
{
smartlist_t *files = smartlist_new();
@@ -2860,7 +2847,8 @@ sandbox_init_filter(void)
sandbox_cfg_allow_rename(&cfg,
tor_strdup(tmp_name), tor_strdup(file_name));
/* steals references */
- sandbox_cfg_allow_open_filename_array(&cfg, file_name, tmp_name, NULL);
+ sandbox_cfg_allow_open_filename(&cfg, file_name);
+ sandbox_cfg_allow_open_filename(&cfg, tmp_name);
});
SMARTLIST_FOREACH(dirs, char *, dir, {
/* steals reference */
@@ -2887,38 +2875,28 @@ sandbox_init_filter(void)
// orport
if (server_mode(get_options())) {
- sandbox_cfg_allow_open_filename_array(&cfg,
- get_datadir_fname2("keys", "secret_id_key"),
- get_datadir_fname2("keys", "secret_onion_key"),
- get_datadir_fname2("keys", "secret_onion_key_ntor"),
- get_datadir_fname2("keys", "secret_onion_key_ntor.tmp"),
- get_datadir_fname2("keys", "secret_id_key.old"),
- get_datadir_fname2("keys", "secret_onion_key.old"),
- get_datadir_fname2("keys", "secret_onion_key_ntor.old"),
- get_datadir_fname2("keys", "secret_onion_key.tmp"),
- get_datadir_fname2("keys", "secret_id_key.tmp"),
- get_datadir_fname2("stats", "bridge-stats"),
- get_datadir_fname2("stats", "bridge-stats.tmp"),
- get_datadir_fname2("stats", "dirreq-stats"),
- get_datadir_fname2("stats", "dirreq-stats.tmp"),
- get_datadir_fname2("stats", "entry-stats"),
- get_datadir_fname2("stats", "entry-stats.tmp"),
- get_datadir_fname2("stats", "exit-stats"),
- get_datadir_fname2("stats", "exit-stats.tmp"),
- get_datadir_fname2("stats", "buffer-stats"),
- get_datadir_fname2("stats", "buffer-stats.tmp"),
- get_datadir_fname2("stats", "conn-stats"),
- get_datadir_fname2("stats", "conn-stats.tmp"),
- get_datadir_fname("approved-routers"),
- get_datadir_fname("fingerprint"),
- get_datadir_fname("fingerprint.tmp"),
- get_datadir_fname("hashed-fingerprint"),
- get_datadir_fname("hashed-fingerprint.tmp"),
- get_datadir_fname("router-stability"),
- get_datadir_fname("router-stability.tmp"),
- tor_strdup("/etc/resolv.conf"),
- NULL, 0
- );
+
+ OPEN_DATADIR2_SUFFIX("keys", "secret_id_key", "tmp");
+ OPEN_DATADIR2_SUFFIX("keys", "secret_onion_key", ".tmp");
+ OPEN_DATADIR2_SUFFIX("keys", "secret_onion_key_ntor", ".tmp");
+ OPEN_DATADIR2("keys", "secret_id_key.old");
+ OPEN_DATADIR2("keys", "secret_onion_key.old");
+ OPEN_DATADIR2("keys", "secret_onion_key_ntor.old");
+
+ OPEN_DATADIR2_SUFFIX("stats", "bridge-stats", ".tmp");
+ OPEN_DATADIR2_SUFFIX("stats", "dirreq-stats", ".tmp");
+
+ OPEN_DATADIR2_SUFFIX("stats", "entry-stats", ".tmp");
+ OPEN_DATADIR2_SUFFIX("stats", "exit-stats", ".tmp");
+ OPEN_DATADIR2_SUFFIX("stats", "buffer-stats", ".tmp");
+ OPEN_DATADIR2_SUFFIX("stats", "conn-stats", ".tmp");
+
+ OPEN_DATADIR("approved-routers");
+ OPEN_DATADIR_SUFFIX("fingerprint", ".tmp");
+ OPEN_DATADIR_SUFFIX("hashed-fingerprint", ".tmp");
+ OPEN_DATADIR_SUFFIX("router-stability", ".tmp");
+
+ OPEN("/etc/resolv.conf");
RENAME_SUFFIX("fingerprint", ".tmp");
RENAME_SUFFIX2("keys", "secret_onion_key_ntor", ".tmp");
@@ -2942,12 +2920,9 @@ sandbox_init_filter(void)
get_datadir_fname2("keys", "secret_onion_key_ntor"),
get_datadir_fname2("keys", "secret_onion_key_ntor.old"));
- sandbox_cfg_allow_stat_filename_array(&cfg,
- get_datadir_fname("keys"),
- get_datadir_fname("stats"),
- get_datadir_fname2("stats", "dirreq-stats"),
- NULL, 0
- );
+ STAT_DATADIR("keys");
+ STAT_DATADIR("stats");
+ STAT_DATADIR2("stats", "dirreq-stats");
}
init_addrinfo();
@@ -2962,31 +2937,6 @@ int
tor_main(int argc, char *argv[])
{
int result = 0;
-#if defined (WINCE)
- WCHAR path [MAX_PATH] = {0};
- WCHAR fullpath [MAX_PATH] = {0};
- PWCHAR p = NULL;
- FILE* redir = NULL;
- FILE* redirdbg = NULL;
-
- // this is to facilitate debugging by opening
- // a file on a folder shared by the wm emulator.
- // if no flashcard (real or emulated) is present,
- // log files will be written in the root folder
- if (find_flashcard_path(path,MAX_PATH) == -1) {
- redir = _wfreopen( L"\\stdout.log", L"w", stdout );
- redirdbg = _wfreopen( L"\\stderr.log", L"w", stderr );
- } else {
- swprintf(fullpath,L"\\%s\\tor",path);
- CreateDirectory(fullpath,NULL);
-
- swprintf(fullpath,L"\\%s\\tor\\stdout.log",path);
- redir = _wfreopen( fullpath, L"w", stdout );
-
- swprintf(fullpath,L"\\%s\\tor\\stderr.log",path);
- redirdbg = _wfreopen( fullpath, L"w", stderr );
- }
-#endif
#ifdef _WIN32
/* Call SetProcessDEPPolicy to permanently enable DEP.
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index fdb549a9ac..576fed0066 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -57,9 +57,9 @@ microdesc_eq_(microdesc_t *a, microdesc_t *b)
HT_PROTOTYPE(microdesc_map, microdesc_t, node,
microdesc_hash_, microdesc_eq_);
-HT_GENERATE(microdesc_map, microdesc_t, node,
+HT_GENERATE2(microdesc_map, microdesc_t, node,
microdesc_hash_, microdesc_eq_, 0.6,
- malloc, realloc, free);
+ tor_reallocarray_, tor_free_)
/** Write the body of <b>md</b> into <b>f</b>, with appropriate annotations.
* On success, return the total number of bytes written, and set
@@ -576,6 +576,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
microdesc_wipe_body(md);
}
}
+ smartlist_free(wrote);
return -1;
}
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 890da0ad17..c7bed9b059 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -83,7 +83,11 @@ static consensus_waiting_for_certs_t
* before the current consensus becomes invalid. */
static time_t time_to_download_next_consensus[N_CONSENSUS_FLAVORS];
/** Download status for the current consensus networkstatus. */
-static download_status_t consensus_dl_status[N_CONSENSUS_FLAVORS];
+static download_status_t consensus_dl_status[N_CONSENSUS_FLAVORS] =
+ {
+ { 0, 0, DL_SCHED_CONSENSUS },
+ { 0, 0, DL_SCHED_CONSENSUS },
+ };
/** True iff we have logged a warning about this OR's version being older than
* listed by the authorities. */
@@ -754,6 +758,9 @@ update_consensus_networkstatus_downloads(time_t now)
resource = networkstatus_get_flavor_name(i);
+ /* Let's make sure we remembered to update consensus_dl_status */
+ tor_assert(consensus_dl_status[i].schedule == DL_SCHED_CONSENSUS);
+
if (!download_status_is_ready(&consensus_dl_status[i], now,
options->TestingConsensusMaxDownloadTries))
continue; /* We failed downloading a consensus too recently. */
@@ -1055,7 +1062,6 @@ routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
a->is_valid != b->is_valid ||
a->is_possible_guard != b->is_possible_guard ||
a->is_bad_exit != b->is_bad_exit ||
- a->is_bad_directory != b->is_bad_directory ||
a->is_hs_dir != b->is_hs_dir ||
a->version_known != b->version_known;
}
@@ -1655,7 +1661,7 @@ networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now)
if (bridge_auth && ri->purpose == ROUTER_PURPOSE_BRIDGE)
dirserv_set_router_is_running(ri, now);
/* then generate and write out status lines for each of them */
- set_routerstatus_from_routerinfo(&rs, node, ri, now, 0, 0, 0, 0);
+ set_routerstatus_from_routerinfo(&rs, node, ri, now, 0, 0);
smartlist_add(statuses, networkstatus_getinfo_helper_single(&rs));
} SMARTLIST_FOREACH_END(ri);
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 7b1f338bd4..f37fb49927 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -53,8 +53,8 @@ node_id_eq(const node_t *node1, const node_t *node2)
}
HT_PROTOTYPE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq);
-HT_GENERATE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq,
- 0.6, malloc, realloc, free);
+HT_GENERATE2(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq,
+ 0.6, tor_reallocarray_, tor_free_)
/** The global nodelist. */
static nodelist_t *the_nodelist=NULL;
@@ -241,7 +241,6 @@ nodelist_set_consensus(networkstatus_t *ns)
node->is_stable = rs->is_stable;
node->is_possible_guard = rs->is_possible_guard;
node->is_exit = rs->is_exit;
- node->is_bad_directory = rs->is_bad_directory;
node->is_bad_exit = rs->is_bad_exit;
node->is_hs_dir = rs->is_hs_dir;
node->ipv6_preferred = 0;
@@ -267,8 +266,7 @@ nodelist_set_consensus(networkstatus_t *ns)
node->is_valid = node->is_running = node->is_hs_dir =
node->is_fast = node->is_stable =
node->is_possible_guard = node->is_exit =
- node->is_bad_exit = node->is_bad_directory =
- node->ipv6_preferred = 0;
+ node->is_bad_exit = node->ipv6_preferred = 0;
}
}
} SMARTLIST_FOREACH_END(node);
@@ -474,8 +472,8 @@ nodelist_assert_ok(void)
/** Return a list of a node_t * for every node we know about. The caller
* MUST NOT modify the list. (You can set and clear flags in the nodes if
* you must, but you must not add or remove nodes.) */
-smartlist_t *
-nodelist_get_list(void)
+MOCK_IMPL(smartlist_t *,
+nodelist_get_list,(void))
{
init_nodelist();
return the_nodelist->nodes;
@@ -517,8 +515,8 @@ node_get_by_hex_id(const char *hex_id)
* the corresponding node_t, or NULL if none exists. Warn the user if
* <b>warn_if_unnamed</b> is set, and they have specified a router by
* nickname, but the Named flag isn't set for that router. */
-const node_t *
-node_get_by_nickname(const char *nickname, int warn_if_unnamed)
+MOCK_IMPL(const node_t *,
+node_get_by_nickname,(const char *nickname, int warn_if_unnamed))
{
const node_t *node;
if (!the_nodelist)
diff --git a/src/or/nodelist.h b/src/or/nodelist.h
index 8e719e012d..cb54cecf1d 100644
--- a/src/or/nodelist.h
+++ b/src/or/nodelist.h
@@ -31,7 +31,8 @@ smartlist_t *nodelist_find_nodes_with_microdesc(const microdesc_t *md);
void nodelist_free_all(void);
void nodelist_assert_ok(void);
-const node_t *node_get_by_nickname(const char *nickname, int warn_if_unnamed);
+MOCK_DECL(const node_t *, node_get_by_nickname,
+ (const char *nickname, int warn_if_unnamed));
void node_get_verbose_nickname(const node_t *node,
char *verbose_name_out);
void node_get_verbose_nickname_by_id(const char *id_digest,
@@ -60,7 +61,7 @@ void node_get_pref_orport(const node_t *node, tor_addr_port_t *ap_out);
void node_get_pref_ipv6_orport(const node_t *node, tor_addr_port_t *ap_out);
int node_has_curve25519_onion_key(const node_t *node);
-smartlist_t *nodelist_get_list(void);
+MOCK_DECL(smartlist_t *, nodelist_get_list, (void));
/* Temporary during transition to multiple addresses. */
void node_get_addr(const node_t *node, tor_addr_t *addr_out);
diff --git a/src/or/ntmain.h b/src/or/ntmain.h
index d3027936cd..d09a413aee 100644
--- a/src/or/ntmain.h
+++ b/src/or/ntmain.h
@@ -13,10 +13,8 @@
#define TOR_NTMAIN_H
#ifdef _WIN32
-#if !defined (WINCE)
#define NT_SERVICE
#endif
-#endif
#ifdef NT_SERVICE
int nt_service_parse_options(int argc, char **argv, int *should_exit);
diff --git a/src/or/or.h b/src/or/or.h
index 1609587717..54cee46ee3 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -14,7 +14,7 @@
#include "orconfig.h"
-#ifdef __COVERITY__
+#if defined(__clang_analyzer__) || defined(__COVERITY__)
/* If we're building for a static analysis, turn on all the off-by-default
* features. */
#ifndef INSTRUMENT_DOWNLOADS
@@ -2139,8 +2139,6 @@ typedef struct routerstatus_t {
* choice as an entry guard. */
unsigned int is_bad_exit:1; /**< True iff this node is a bad choice for
* an exit node. */
- unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
- * underpowered, or otherwise useless? */
unsigned int is_hs_dir:1; /**< True iff this router is a v2-or-later hidden
* service directory. */
/** True iff we know version info for this router. (i.e., a "v" entry was
@@ -2151,9 +2149,6 @@ typedef struct routerstatus_t {
/** True iff this router is a version that, if it caches directory info,
* we can get microdescriptors from. */
unsigned int version_supports_microdesc_cache:1;
- /** True iff this router is a version that allows DATA cells to arrive on
- * a stream before it has sent a CONNECTED cell. */
- unsigned int version_supports_optimistic_data:1;
/** True iff this router has a version that allows it to accept EXTEND2
* cells */
unsigned int version_supports_extend2_cells:1;
@@ -2300,8 +2295,6 @@ typedef struct node_t {
unsigned int is_exit:1; /**< Do we think this is an OK exit? */
unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
* or otherwise nasty? */
- unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
- * underpowered, or otherwise useless? */
unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
* directory according to the authorities. */
@@ -2865,8 +2858,8 @@ typedef struct circuit_t {
/** Unique ID for measuring tunneled network status requests. */
uint64_t dirreq_id;
- /** Next circuit in linked list of all circuits (global_circuitlist). */
- TOR_LIST_ENTRY(circuit_t) head;
+ /** Index in smartlist of all circuits (global_circuitlist). */
+ int global_circuitlist_idx;
/** Next circuit in the doubly-linked ring of circuits waiting to add
* cells to n_conn. NULL if we have no cells pending, or if we're not
@@ -3403,6 +3396,8 @@ typedef struct {
int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which
* each log message occurs? */
+ int TruncateLogFile; /**< Boolean: Should we truncate the log file
+ before we start writing? */
char *DebugLogFile; /**< Where to send verbose log messages. */
char *DataDirectory; /**< OR only: where to store long-term data. */
@@ -3531,8 +3526,6 @@ typedef struct {
int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */
int V3AuthoritativeDir; /**< Boolean: is this an authoritative directory
* for version 3 directories? */
- int NamingAuthoritativeDir; /**< Boolean: is this an authoritative directory
- * that's willing to bind names? */
int VersioningAuthoritativeDir; /**< Boolean: is this an authoritative
* directory that's willing to recommend
* versions? */
@@ -3742,8 +3735,6 @@ typedef struct {
config_line_t *NodeFamilies; /**< List of config lines for
* node families */
smartlist_t *NodeFamilySets; /**< List of parsed NodeFamilies values. */
- config_line_t *AuthDirBadDir; /**< Address policy for descriptors to
- * mark as bad dir mirrors. */
config_line_t *AuthDirBadExit; /**< Address policy for descriptors to
* mark as bad exits. */
config_line_t *AuthDirReject; /**< Address policy for descriptors to
@@ -3752,23 +3743,18 @@ typedef struct {
* never mark as valid. */
/** @name AuthDir...CC
*
- * Lists of country codes to mark as BadDir, BadExit, or Invalid, or to
+ * Lists of country codes to mark as BadExit, or Invalid, or to
* reject entirely.
*
* @{
*/
- smartlist_t *AuthDirBadDirCCs;
smartlist_t *AuthDirBadExitCCs;
smartlist_t *AuthDirInvalidCCs;
smartlist_t *AuthDirRejectCCs;
/**@}*/
- int AuthDirListBadDirs; /**< True iff we should list bad dirs,
- * and vote for all other dir mirrors as good. */
int AuthDirListBadExits; /**< True iff we should list bad exits,
* and vote for all other exits as good. */
- int AuthDirRejectUnlisted; /**< Boolean: do we reject all routers that
- * aren't named in our fingerprint file? */
int AuthDirMaxServersPerAddr; /**< Do not permit more than this
* number of servers per IP address. */
int AuthDirMaxServersPerAuthAddr; /**< Do not permit more than this
@@ -3789,6 +3775,11 @@ typedef struct {
uint64_t AccountingMax; /**< How many bytes do we allow per accounting
* interval before hibernation? 0 for "never
* hibernate." */
+ /** How do we determine when our AccountingMax has been reached?
+ * "max" for when in or out reaches AccountingMax
+ * "sum for when in plus out reaches AccountingMax */
+ char *AccountingRule_option;
+ enum { ACCT_MAX, ACCT_SUM } AccountingRule;
/** Base64-encoded hash of accepted passwords for the control system. */
config_line_t *HashedControlPassword;
@@ -3921,8 +3912,11 @@ typedef struct {
* instead of a hostname. */
int WarnUnsafeSocks;
- /** If true, the user wants us to collect statistics on clients
+ /** If true, we're configured to collect statistics on clients
* requesting network statuses from us as directory. */
+ int DirReqStatistics_option;
+ /** Internal variable to remember whether we're actually acting on
+ * DirReqStatistics_option -- yes if it's set and we're a server, else no. */
int DirReqStatistics;
/** If true, the user wants us to collect statistics on port usage. */
diff --git a/src/or/policies.c b/src/or/policies.c
index 8a91509a77..7090eda2c4 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -29,9 +29,6 @@ static smartlist_t *authdir_reject_policy = NULL;
* to be marked as valid in our networkstatus. */
static smartlist_t *authdir_invalid_policy = NULL;
/** Policy that addresses for incoming router descriptors must <b>not</b>
- * match in order to not be marked as BadDirectory. */
-static smartlist_t *authdir_baddir_policy = NULL;
-/** Policy that addresses for incoming router descriptors must <b>not</b>
* match in order to not be marked as BadExit. */
static smartlist_t *authdir_badexit_policy = NULL;
@@ -65,6 +62,13 @@ static const char *private_nets[] = {
NULL
};
+static int policies_parse_exit_policy_internal(config_line_t *cfg,
+ smartlist_t **dest,
+ int ipv6_exit,
+ int rejectprivate,
+ uint32_t local_address,
+ int add_default_policy);
+
/** Replace all "private" entries in *<b>policy</b> with their expanded
* equivalents. */
void
@@ -400,17 +404,6 @@ authdir_policy_valid_address(uint32_t addr, uint16_t port)
return !addr_is_in_cc_list(addr, get_options()->AuthDirInvalidCCs);
}
-/** Return 1 if <b>addr</b>:<b>port</b> should be marked as a bad dir,
- * based on <b>authdir_baddir_policy</b>. Else return 0.
- */
-int
-authdir_policy_baddir_address(uint32_t addr, uint16_t port)
-{
- if (! addr_policy_permits_address(addr, port, authdir_baddir_policy))
- return 1;
- return addr_is_in_cc_list(addr, get_options()->AuthDirBadDirCCs);
-}
-
/** Return 1 if <b>addr</b>:<b>port</b> should be marked as a bad exit,
* based on <b>authdir_badexit_policy</b>. Else return 0.
*/
@@ -437,11 +430,9 @@ validate_addr_policies(const or_options_t *options, char **msg)
smartlist_t *addr_policy=NULL;
*msg = NULL;
- if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
- options->IPv6Exit,
- options->ExitPolicyRejectPrivate, 0,
- !options->BridgeRelay))
+ if (policies_parse_exit_policy_from_options(options,0,&addr_policy)) {
REJECT("Error in ExitPolicy entry.");
+ }
/* The rest of these calls *append* to addr_policy. So don't actually
* use the results for anything other than checking if they parse! */
@@ -455,9 +446,6 @@ validate_addr_policies(const or_options_t *options, char **msg)
if (parse_addr_policy(options->AuthDirInvalid, &addr_policy,
ADDR_POLICY_REJECT))
REJECT("Error in AuthDirInvalid entry.");
- if (parse_addr_policy(options->AuthDirBadDir, &addr_policy,
- ADDR_POLICY_REJECT))
- REJECT("Error in AuthDirBadDir entry.");
if (parse_addr_policy(options->AuthDirBadExit, &addr_policy,
ADDR_POLICY_REJECT))
REJECT("Error in AuthDirBadExit entry.");
@@ -535,9 +523,6 @@ policies_parse_from_options(const or_options_t *options)
if (load_policy_from_option(options->AuthDirInvalid, "AuthDirInvalid",
&authdir_invalid_policy, ADDR_POLICY_REJECT) < 0)
ret = -1;
- if (load_policy_from_option(options->AuthDirBadDir, "AuthDirBadDir",
- &authdir_baddir_policy, ADDR_POLICY_REJECT) < 0)
- ret = -1;
if (load_policy_from_option(options->AuthDirBadExit, "AuthDirBadExit",
&authdir_badexit_policy, ADDR_POLICY_REJECT) < 0)
ret = -1;
@@ -629,8 +614,8 @@ policy_hash(const policy_map_ent_t *ent)
HT_PROTOTYPE(policy_map, policy_map_ent_t, node, policy_hash,
policy_eq)
-HT_GENERATE(policy_map, policy_map_ent_t, node, policy_hash,
- policy_eq, 0.6, malloc, realloc, free)
+HT_GENERATE2(policy_map, policy_map_ent_t, node, policy_hash,
+ policy_eq, 0.6, tor_reallocarray_, tor_free_)
/** Given a pointer to an addr_policy_t, return a copy of the pointer to the
* "canonical" copy of that addr_policy_t; the canonical copy is a single
@@ -769,9 +754,9 @@ compare_unknown_tor_addr_to_addr_policy(uint16_t port,
* We could do better by assuming that some ranges never match typical
* addresses (127.0.0.1, and so on). But we'll try this for now.
*/
-addr_policy_result_t
-compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port,
- const smartlist_t *policy)
+MOCK_IMPL(addr_policy_result_t,
+compare_tor_addr_to_addr_policy,(const tor_addr_t *addr, uint16_t port,
+ const smartlist_t *policy))
{
if (!policy) {
/* no policy? accept all. */
@@ -968,11 +953,12 @@ exit_policy_remove_redundancies(smartlist_t *dest)
* the functions used to parse the exit policy from a router descriptor,
* see router_add_exit_policy.
*/
-int
-policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
- int ipv6_exit,
- int rejectprivate, uint32_t local_address,
- int add_default_policy)
+static int
+policies_parse_exit_policy_internal(config_line_t *cfg, smartlist_t **dest,
+ int ipv6_exit,
+ int rejectprivate,
+ uint32_t local_address,
+ int add_default_policy)
{
if (!ipv6_exit) {
append_exit_policy_string(dest, "reject *6:*");
@@ -998,6 +984,68 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
return 0;
}
+/** Parse exit policy in <b>cfg</b> into <b>dest</b> smartlist.
+ *
+ * Add entry that rejects all IPv6 destinations unless
+ * <b>EXIT_POLICY_IPV6_ENABLED</b> bit is set in <b>options</b> bitmask.
+ *
+ * If <b>EXIT_POLICY_REJECT_PRIVATE</b> bit is set in <b>options</b>,
+ * do add entry that rejects all destinations in private subnetwork
+ * Tor is running in.
+ *
+ * Respectively, if <b>EXIT_POLICY_ADD_DEFAULT</b> bit is set, add
+ * default exit policy entries to <b>result</b> smartlist.
+ */
+int
+policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
+ exit_policy_parser_cfg_t options,
+ uint32_t local_address)
+{
+ int ipv6_enabled = (options & EXIT_POLICY_IPV6_ENABLED) ? 1 : 0;
+ int reject_private = (options & EXIT_POLICY_REJECT_PRIVATE) ? 1 : 0;
+ int add_default = (options & EXIT_POLICY_ADD_DEFAULT) ? 1 : 0;
+
+ return policies_parse_exit_policy_internal(cfg,dest,ipv6_enabled,
+ reject_private,
+ local_address,
+ add_default);
+}
+
+/** Parse <b>ExitPolicy</b> member of <b>or_options</b> into <b>result</b>
+ * smartlist.
+ * If <b>or_options->IPv6Exit</b> is false, add an entry that
+ * rejects all IPv6 destinations.
+ *
+ * If <b>or_options->ExitPolicyRejectPrivate</b> is true, add entry that
+ * rejects all destinations in the private subnetwork of machine Tor
+ * instance is running in.
+ *
+ * If <b>or_options->BridgeRelay</b> is false, add entries of default
+ * Tor exit policy into <b>result</b> smartlist.
+ */
+int
+policies_parse_exit_policy_from_options(const or_options_t *or_options,
+ uint32_t local_address,
+ smartlist_t **result)
+{
+ exit_policy_parser_cfg_t parser_cfg = 0;
+
+ if (or_options->IPv6Exit) {
+ parser_cfg |= EXIT_POLICY_IPV6_ENABLED;
+ }
+
+ if (or_options->ExitPolicyRejectPrivate) {
+ parser_cfg |= EXIT_POLICY_REJECT_PRIVATE;
+ }
+
+ if (!or_options->BridgeRelay) {
+ parser_cfg |= EXIT_POLICY_ADD_DEFAULT;
+ }
+
+ return policies_parse_exit_policy(or_options->ExitPolicy,result,
+ parser_cfg,local_address);
+}
+
/** Add "reject *:*" to the end of the policy in *<b>dest</b>, allocating
* *<b>dest</b> as needed. */
void
@@ -1334,9 +1382,9 @@ policy_summary_add_item(smartlist_t *summary, addr_policy_t *p)
* The summary will either be an "accept" plus a comma-separated list of port
* ranges or a "reject" plus port-ranges, depending on which is shorter.
*
- * If no exits are allowed at all then NULL is returned, if no ports
- * are blocked instead of "reject " we return "accept 1-65535" (this
- * is an exception to the shorter-representation-wins rule).
+ * If no exits are allowed at all then "reject 1-65535" is returned. If no
+ * ports are blocked instead of "reject " we return "accept 1-65535". (These
+ * are an exception to the shorter-representation-wins rule).
*/
char *
policy_summarize(smartlist_t *policy, sa_family_t family)
@@ -1766,8 +1814,6 @@ policies_free_all(void)
authdir_reject_policy = NULL;
addr_policy_list_free(authdir_invalid_policy);
authdir_invalid_policy = NULL;
- addr_policy_list_free(authdir_baddir_policy);
- authdir_baddir_policy = NULL;
addr_policy_list_free(authdir_badexit_policy);
authdir_badexit_policy = NULL;
diff --git a/src/or/policies.h b/src/or/policies.h
index 91ac427492..0b47b761ec 100644
--- a/src/or/policies.h
+++ b/src/or/policies.h
@@ -18,6 +18,12 @@
*/
#define POLICY_BUF_LEN 72
+#define EXIT_POLICY_IPV6_ENABLED (1 << 0)
+#define EXIT_POLICY_REJECT_PRIVATE (1 << 1)
+#define EXIT_POLICY_ADD_DEFAULT (1 << 2)
+
+typedef int exit_policy_parser_cfg_t;
+
int firewall_is_fascist_or(void);
int fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port);
int fascist_firewall_allows_or(const routerinfo_t *ri);
@@ -27,7 +33,6 @@ int dir_policy_permits_address(const tor_addr_t *addr);
int socks_policy_permits_address(const tor_addr_t *addr);
int authdir_policy_permits_address(uint32_t addr, uint16_t port);
int authdir_policy_valid_address(uint32_t addr, uint16_t port);
-int authdir_policy_baddir_address(uint32_t addr, uint16_t port);
int authdir_policy_badexit_address(uint32_t addr, uint16_t port);
int validate_addr_policies(const or_options_t *options, char **msg);
@@ -37,16 +42,24 @@ int policies_parse_from_options(const or_options_t *options);
addr_policy_t *addr_policy_get_canonical_entry(addr_policy_t *ent);
int cmp_addr_policies(smartlist_t *a, smartlist_t *b);
-addr_policy_result_t compare_tor_addr_to_addr_policy(const tor_addr_t *addr,
- uint16_t port, const smartlist_t *policy);
+MOCK_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
+ (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr,
uint16_t port, const node_t *node);
+/*
int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
int ipv6exit,
int rejectprivate, uint32_t local_address,
int add_default_policy);
+*/
+int policies_parse_exit_policy_from_options(const or_options_t *or_options,
+ uint32_t local_address,
+ smartlist_t **result);
+int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
+ exit_policy_parser_cfg_t options,
+ uint32_t local_address);
void policies_exit_policy_append_reject_star(smartlist_t **dest);
void addr_policy_append_reject_addr(smartlist_t **dest,
const tor_addr_t *addr);
diff --git a/src/or/reasons.c b/src/or/reasons.c
index 750e89bbe7..1a53a93d88 100644
--- a/src/or/reasons.c
+++ b/src/or/reasons.c
@@ -367,7 +367,7 @@ circuit_end_reason_to_control_string(int reason)
}
}
-/** Return a string corresponding to a SOCKS4 reponse code. */
+/** Return a string corresponding to a SOCKS4 response code. */
const char *
socks4_response_code_to_string(uint8_t code)
{
@@ -385,7 +385,7 @@ socks4_response_code_to_string(uint8_t code)
}
}
-/** Return a string corresponding to a SOCKS5 reponse code. */
+/** Return a string corresponding to a SOCKS5 response code. */
const char *
socks5_response_code_to_string(uint8_t code)
{
diff --git a/src/or/relay.c b/src/or/relay.c
index 4d71157db8..d97c84fb07 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -2328,15 +2328,15 @@ packed_cell_free(packed_cell_t *cell)
void
dump_cell_pool_usage(int severity)
{
- circuit_t *c;
int n_circs = 0;
int n_cells = 0;
- TOR_LIST_FOREACH(c, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, c) {
n_cells += c->n_chan_cells.n;
if (!CIRCUIT_IS_ORIGIN(c))
n_cells += TO_OR_CIRCUIT(c)->p_chan_cells.n;
++n_circs;
}
+ SMARTLIST_FOREACH_END(c);
tor_log(severity, LD_MM,
"%d cells allocated on %d circuits. %d cells leaked.",
n_cells, n_circs, (int)total_cells_allocated - n_cells);
@@ -2439,6 +2439,7 @@ cell_queues_check_size(void)
{
size_t alloc = cell_queues_get_total_allocation();
alloc += buf_get_total_allocation();
+ alloc += tor_zlib_get_total_allocation();
if (alloc >= get_options()->MaxMemInQueues) {
circuits_handle_oom(alloc);
return 1;
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 19a8cef1bf..bc34695bc0 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -376,9 +376,8 @@ rend_client_rendcirc_has_opened(origin_circuit_t *circ)
static void
rend_client_close_other_intros(const char *onion_address)
{
- circuit_t *c;
/* abort parallel intro circs, if any */
- TOR_LIST_FOREACH(c, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, c) {
if ((c->purpose == CIRCUIT_PURPOSE_C_INTRODUCING ||
c->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) &&
!c->marked_for_close && CIRCUIT_IS_ORIGIN(c)) {
@@ -393,6 +392,7 @@ rend_client_close_other_intros(const char *onion_address)
}
}
}
+ SMARTLIST_FOREACH_END(c);
}
/** Called when get an ACK or a NAK for a REND_INTRODUCE1 cell.
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index a664b5d501..269cd65679 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -155,7 +155,7 @@ rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
}
/* Calculate current time-period. */
time_period = get_time_period(now, 0, service_id_binary);
- /* Calculate secret-id-part = h(time-period + replica). */
+ /* Calculate secret-id-part = h(time-period | replica). */
get_secret_id_part_bytes(secret_id_part, time_period, descriptor_cookie,
replica);
/* Calculate descriptor ID. */
@@ -528,7 +528,7 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
return -1;
}
/* Base64-encode introduction points. */
- ipos_base64 = tor_malloc_zero(ipos_len * 2);
+ ipos_base64 = tor_calloc(ipos_len, 2);
if (base64_encode(ipos_base64, ipos_len * 2, ipos, ipos_len)<0) {
log_warn(LD_REND, "Could not encode introduction point string to "
"base64. length=%d", (int)ipos_len);
@@ -556,7 +556,7 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
char desc_digest[DIGEST_LEN];
rend_encoded_v2_service_descriptor_t *enc =
tor_malloc_zero(sizeof(rend_encoded_v2_service_descriptor_t));
- /* Calculate secret-id-part = h(time-period + cookie + replica). */
+ /* Calculate secret-id-part = h(time-period | cookie | replica). */
get_secret_id_part_bytes(secret_id_part, time_period, descriptor_cookie,
k);
base32_encode(secret_id_part_base32, sizeof(secret_id_part_base32),
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index d89cdf6bed..1bcd17bc44 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -188,7 +188,7 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
"Unable to send INTRODUCE2 cell to Tor client.");
goto err;
}
- /* And sent an ack down Alice's circuit. Empty body means succeeded. */
+ /* And send an ack down Alice's circuit. Empty body means succeeded. */
if (relay_send_command_from_edge(0,TO_CIRCUIT(circ),
RELAY_COMMAND_INTRODUCE_ACK,
NULL,0,NULL)) {
@@ -199,7 +199,7 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
return 0;
err:
- /* Send the client an NACK */
+ /* Send the client a NACK */
nak_body[0] = 1;
if (relay_send_command_from_edge(0,TO_CIRCUIT(circ),
RELAY_COMMAND_INTRODUCE_ACK,
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index a7c1e32f15..31b612bb26 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -524,7 +524,6 @@ rend_config_services(const or_options_t *options, int validate_only)
* other ones. */
if (old_service_list && !validate_only) {
smartlist_t *surviving_services = smartlist_new();
- circuit_t *circ;
/* Copy introduction points to new services. */
/* XXXX This is O(n^2), but it's only called on reconfigure, so it's
@@ -544,7 +543,7 @@ rend_config_services(const or_options_t *options, int validate_only)
/* XXXX it would be nicer if we had a nicer abstraction to use here,
* so we could just iterate over the list of services to close, but
* once again, this isn't critical-path code. */
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!circ->marked_for_close &&
circ->state == CIRCUIT_STATE_OPEN &&
(circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
@@ -569,6 +568,7 @@ rend_config_services(const or_options_t *options, int validate_only)
/* XXXX Is there another reason we should use here? */
}
}
+ SMARTLIST_FOREACH_END(circ);
smartlist_free(surviving_services);
SMARTLIST_FOREACH(old_service_list, rend_service_t *, ptr,
rend_service_free(ptr));
@@ -1446,10 +1446,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
memwipe(hexcookie, 0, sizeof(hexcookie));
/* Free the parsed cell */
- if (parsed_req) {
- rend_service_free_intro(parsed_req);
- parsed_req = NULL;
- }
+ rend_service_free_intro(parsed_req);
/* Free rp if we must */
if (need_rp_free) extend_info_free(rp);
@@ -1539,7 +1536,6 @@ void
rend_service_free_intro(rend_intro_cell_t *request)
{
if (!request) {
- log_info(LD_BUG, "rend_service_free_intro() called with NULL request!");
return;
}
@@ -1648,8 +1644,9 @@ rend_service_begin_parse_intro(const uint8_t *request,
goto done;
err:
- if (rv) rend_service_free_intro(rv);
+ rend_service_free_intro(rv);
rv = NULL;
+
if (err_msg_out && !err_msg) {
tor_asprintf(&err_msg,
"unknown INTRODUCE%d error",
@@ -1757,7 +1754,7 @@ rend_service_parse_intro_for_v2(
/*
* We accept version 3 too so that the v3 parser can call this with
- * and adjusted buffer for the latter part of a v3 cell, which is
+ * an adjusted buffer for the latter part of a v3 cell, which is
* identical to a v2 cell.
*/
if (!(intro->version == 2 ||
@@ -1985,7 +1982,7 @@ rend_service_decrypt_intro(
char service_id[REND_SERVICE_ID_LEN_BASE32+1];
ssize_t key_len;
uint8_t buf[RELAY_PAYLOAD_SIZE];
- int result, status = 0;
+ int result, status = -1;
if (!intro || !key) {
if (err_msg_out) {
@@ -2064,6 +2061,8 @@ rend_service_decrypt_intro(
intro->plaintext = tor_malloc(intro->plaintext_len);
memcpy(intro->plaintext, buf, intro->plaintext_len);
+ status = 0;
+
goto done;
err:
@@ -2072,7 +2071,6 @@ rend_service_decrypt_intro(
"unknown INTRODUCE%d error decrypting encrypted part",
intro ? (int)(intro->type) : -1);
}
- if (status >= 0) status = -1;
done:
if (err_msg_out) *err_msg_out = err_msg;
@@ -2099,7 +2097,7 @@ rend_service_parse_intro_plaintext(
char *err_msg = NULL;
ssize_t ver_specific_len, ver_invariant_len;
uint8_t version;
- int status = 0;
+ int status = -1;
if (!intro) {
if (err_msg_out) {
@@ -2158,6 +2156,7 @@ rend_service_parse_intro_plaintext(
(int)(intro->type),
(long)(intro->plaintext_len));
status = -6;
+ goto err;
} else {
memcpy(intro->rc,
intro->plaintext + ver_specific_len,
@@ -2170,6 +2169,7 @@ rend_service_parse_intro_plaintext(
/* Flag it as being fully parsed */
intro->parsed = 1;
+ status = 0;
goto done;
err:
@@ -2178,7 +2178,6 @@ rend_service_parse_intro_plaintext(
"unknown INTRODUCE%d error parsing encrypted part",
intro ? (int)(intro->type) : -1);
}
- if (status >= 0) status = -1;
done:
if (err_msg_out) *err_msg_out = err_msg;
@@ -2384,8 +2383,7 @@ static int
count_established_intro_points(const char *query)
{
int num_ipos = 0;
- circuit_t *circ;
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
if (!circ->marked_for_close &&
circ->state == CIRCUIT_STATE_OPEN &&
(circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
@@ -2396,6 +2394,7 @@ count_established_intro_points(const char *query)
num_ipos++;
}
}
+ SMARTLIST_FOREACH_END(circ);
return num_ipos;
}
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 72de54c0c9..cd92b0adc5 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -1998,12 +1998,9 @@ void
rep_hist_exit_stats_init(time_t now)
{
start_of_exit_stats_interval = now;
- exit_bytes_read = tor_malloc_zero(EXIT_STATS_NUM_PORTS *
- sizeof(uint64_t));
- exit_bytes_written = tor_malloc_zero(EXIT_STATS_NUM_PORTS *
- sizeof(uint64_t));
- exit_streams = tor_malloc_zero(EXIT_STATS_NUM_PORTS *
- sizeof(uint32_t));
+ exit_bytes_read = tor_calloc(EXIT_STATS_NUM_PORTS, sizeof(uint64_t));
+ exit_bytes_written = tor_calloc(EXIT_STATS_NUM_PORTS, sizeof(uint64_t));
+ exit_streams = tor_calloc(EXIT_STATS_NUM_PORTS, sizeof(uint32_t));
}
/** Reset counters for exit port statistics. */
@@ -2474,7 +2471,6 @@ rep_hist_format_buffer_stats(time_t now)
time_t
rep_hist_buffer_stats_write(time_t now)
{
- circuit_t *circ;
char *str = NULL;
if (!start_of_buffer_stats_interval)
@@ -2483,9 +2479,10 @@ rep_hist_buffer_stats_write(time_t now)
goto done; /* Not ready to write */
/* Add open circuits to the history. */
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head) {
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
rep_hist_buffer_stats_add_circ(circ, now);
}
+ SMARTLIST_FOREACH_END(circ);
/* Generate history string. */
str = rep_hist_format_buffer_stats(now);
@@ -2572,7 +2569,7 @@ rep_hist_format_desc_stats(time_t now)
size = digestmap_size(served_descs);
if (size > 0) {
- vals = tor_malloc(size * sizeof(int));
+ vals = tor_calloc(size, sizeof(int));
for (iter = digestmap_iter_init(served_descs);
!digestmap_iter_done(iter);
iter = digestmap_iter_next(served_descs, iter)) {
@@ -2727,8 +2724,8 @@ bidi_map_ent_hash(const bidi_map_entry_t *entry)
HT_PROTOTYPE(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
bidi_map_ent_eq);
-HT_GENERATE(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
- bidi_map_ent_eq, 0.6, malloc, realloc, free);
+HT_GENERATE2(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
+ bidi_map_ent_eq, 0.6, tor_reallocarray_, tor_free_)
/* DOCDOC bidi_map_free */
static void
diff --git a/src/or/router.c b/src/or/router.c
index 2cdbb0c8bb..dbe985ac78 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -911,9 +911,8 @@ init_keys(void)
const char *m = NULL;
routerinfo_t *ri;
/* We need to add our own fingerprint so it gets recognized. */
- if (dirserv_add_own_fingerprint(options->Nickname,
- get_server_identity_key())) {
- log_err(LD_GENERAL,"Error adding own fingerprint to approved set");
+ if (dirserv_add_own_fingerprint(get_server_identity_key())) {
+ log_err(LD_GENERAL,"Error adding own fingerprint to set of relays");
return -1;
}
if (mydesc) {
@@ -1081,6 +1080,7 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
* they're confused or to get statistics. */
int interval_length = accounting_get_interval_length();
uint32_t effective_bw = get_effective_bwrate(options);
+ uint64_t acc_bytes;
if (!interval_length) {
log_warn(LD_BUG, "An accounting interval is not allowed to be zero "
"seconds long. Raising to 1.");
@@ -1091,8 +1091,12 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
"accounting interval length %d", effective_bw,
U64_PRINTF_ARG(options->AccountingMax),
interval_length);
+
+ acc_bytes = options->AccountingMax;
+ if (get_options()->AccountingRule == ACCT_SUM)
+ acc_bytes /= 2;
if (effective_bw >=
- options->AccountingMax / interval_length) {
+ acc_bytes / interval_length) {
new_choice = 0;
reason = "AccountingMax enabled";
}
@@ -1856,10 +1860,8 @@ router_rebuild_descriptor(int force)
/* DNS is screwed up; don't claim to be an exit. */
policies_exit_policy_append_reject_star(&ri->exit_policy);
} else {
- policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
- options->IPv6Exit,
- options->ExitPolicyRejectPrivate,
- ri->addr, !options->BridgeRelay);
+ policies_parse_exit_policy_from_options(options,ri->addr,
+ &ri->exit_policy);
}
ri->policy_is_reject_star =
policy_is_reject_star(ri->exit_policy, AF_INET) &&
@@ -1879,7 +1881,7 @@ router_rebuild_descriptor(int force)
family = smartlist_new();
ri->declared_family = smartlist_new();
smartlist_split_string(family, options->MyFamily, ",",
- SPLIT_SKIP_SPACE|SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK|SPLIT_STRIP_SPACE, 0);
SMARTLIST_FOREACH_BEGIN(family, char *, name) {
const node_t *member;
if (!strcasecmp(name, options->Nickname))
@@ -2063,7 +2065,8 @@ mark_my_descriptor_dirty(const char *reason)
}
/** How frequently will we republish our descriptor because of large (factor
- * of 2) shifts in estimated bandwidth? */
+ * of 2) shifts in estimated bandwidth? Note: We don't use this constant
+ * if our previous bandwidth estimate was exactly 0. */
#define MAX_BANDWIDTH_CHANGE_FREQ (20*60)
/** Check whether bandwidth has changed a lot since the last time we announced
@@ -2081,7 +2084,7 @@ check_descriptor_bandwidth_changed(time_t now)
if ((prev != cur && (!prev || !cur)) ||
cur > prev*2 ||
cur < prev/2) {
- if (last_changed+MAX_BANDWIDTH_CHANGE_FREQ < now) {
+ if (last_changed+MAX_BANDWIDTH_CHANGE_FREQ < now || !prev) {
log_info(LD_GENERAL,
"Measured bandwidth has changed; rebuilding descriptor.");
mark_my_descriptor_dirty("bandwidth has changed");
@@ -2371,7 +2374,8 @@ router_dump_router_to_string(routerinfo_t *router,
has_extra_info_digest ? "extra-info-digest " : "",
has_extra_info_digest ? extra_info_digest : "",
has_extra_info_digest ? "\n" : "",
- options->DownloadExtraInfo ? "caches-extra-info\n" : "",
+ (options->DownloadExtraInfo || options->V3AuthoritativeDir) ?
+ "caches-extra-info\n" : "",
onion_pkey, identity_pkey,
family_line,
we_are_hibernating() ? "hibernating 1\n" : "",
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 32cbe19379..22489a4476 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -448,9 +448,10 @@ trusted_dirs_flush_certs_to_disk(void)
trusted_dir_servers_certs_changed = 0;
}
-/** Remove all v3 authority certificates that have been superseded for more
- * than 48 hours. (If the most recent cert was published more than 48 hours
- * ago, then we aren't going to get any consensuses signed with older
+/** Remove all expired v3 authority certificates that have been superseded for
+ * more than 48 hours or, if not expired, that were published more than 7 days
+ * before being superseded. (If the most recent cert was published more than 48
+ * hours ago, then we aren't going to get any consensuses signed with older
* keys.) */
static void
trusted_dirs_remove_old_certs(void)
@@ -474,6 +475,8 @@ trusted_dirs_remove_old_certs(void)
time_t cert_published;
if (newest == cert)
continue;
+ /* resolve spurious clang shallow analysis null pointer errors */
+ tor_assert(cert);
expired = now > cert->expires;
cert_published = cert->cache_info.published_on;
/* Store expired certs for 48 hours after a newer arrives;
@@ -488,6 +491,7 @@ trusted_dirs_remove_old_certs(void)
} SMARTLIST_FOREACH_END(cert);
}
} DIGESTMAP_FOREACH_END;
+#undef DEAD_CERT_LIFETIME
#undef OLD_CERT_LIFETIME
trusted_dirs_flush_certs_to_disk();
@@ -1438,7 +1442,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags)
/* Find all the running dirservers we know about. */
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
- int is_trusted;
+ int is_trusted, is_trusted_extrainfo;
int is_overloaded;
tor_addr_t addr;
const routerstatus_t *status = node->rs;
@@ -1448,13 +1452,13 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags)
if (!node->is_running || !status->dir_port || !node->is_valid)
continue;
- if (node->is_bad_directory)
- continue;
if (requireother && router_digest_is_me(node->identity))
continue;
is_trusted = router_digest_is_trusted_dir(node->identity);
+ is_trusted_extrainfo = router_digest_is_trusted_dir_type(
+ node->identity, EXTRAINFO_DIRINFO);
if ((type & EXTRAINFO_DIRINFO) &&
- !router_supports_extrainfo(node->identity, 0))
+ !router_supports_extrainfo(node->identity, is_trusted_extrainfo))
continue;
if ((type & MICRODESC_DIRINFO) && !is_trusted &&
!node->rs->version_supports_microdesc_cache)
@@ -1530,7 +1534,7 @@ dirserver_choose_by_weight(const smartlist_t *servers, double authority_weight)
u64_dbl_t *weights;
const dir_server_t *ds;
- weights = tor_malloc(sizeof(u64_dbl_t) * n);
+ weights = tor_calloc(sizeof(u64_dbl_t), n);
for (i = 0; i < n; ++i) {
ds = smartlist_get(servers, i);
weights[i].dbl = ds->weight;
@@ -1802,15 +1806,16 @@ scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries,
uint64_t *total_out)
{
double total = 0.0;
- double scale_factor;
+ double scale_factor = 0.0;
int i;
/* big, but far away from overflowing an int64_t */
-#define SCALE_TO_U64_MAX (INT64_MAX / 4)
+#define SCALE_TO_U64_MAX ((int64_t) (INT64_MAX / 4))
for (i = 0; i < n_entries; ++i)
total += entries[i].dbl;
- scale_factor = SCALE_TO_U64_MAX / total;
+ if (total > 0.0)
+ scale_factor = SCALE_TO_U64_MAX / total;
for (i = 0; i < n_entries; ++i)
entries[i].u64 = tor_llround(entries[i].dbl * scale_factor);
@@ -2038,7 +2043,7 @@ compute_weighted_bandwidths(const smartlist_t *sl,
Web /= weight_scale;
Wdb /= weight_scale;
- bandwidths = tor_malloc_zero(sizeof(u64_dbl_t)*smartlist_len(sl));
+ bandwidths = tor_calloc(sizeof(u64_dbl_t), smartlist_len(sl));
// Cycle through smartlist and total the bandwidth.
SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
@@ -2185,7 +2190,7 @@ smartlist_choose_node_by_bandwidth(const smartlist_t *sl,
/* First count the total bandwidth weight, and make a list
* of each value. We use UINT64_MAX to indicate "unknown". */
- bandwidths = tor_malloc_zero(sizeof(u64_dbl_t)*smartlist_len(sl));
+ bandwidths = tor_calloc(sizeof(u64_dbl_t), smartlist_len(sl));
fast_bits = bitarray_init_zero(smartlist_len(sl));
exit_bits = bitarray_init_zero(smartlist_len(sl));
guard_bits = bitarray_init_zero(smartlist_len(sl));
@@ -3292,6 +3297,14 @@ routerlist_reset_warnings(void)
networkstatus_reset_warnings();
}
+/** Return 1 if the signed descriptor of this router is older than
+ * <b>seconds</b> seconds. Otherwise return 0. */
+MOCK_IMPL(int,
+router_descriptor_is_older_than,(const routerinfo_t *router, int seconds))
+{
+ return router->cache_info.published_on < time(NULL) - seconds;
+}
+
/** Add <b>router</b> to the routerlist, if we don't already have it. Replace
* older entries (if any) with the same key. Note: Callers should not hold
* their pointers to <b>router</b> if this function fails; <b>router</b>
@@ -3461,7 +3474,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
}
if (!in_consensus && from_cache &&
- router->cache_info.published_on < time(NULL) - OLD_ROUTER_DESC_MAX_AGE) {
+ router_descriptor_is_older_than(router, OLD_ROUTER_DESC_MAX_AGE)) {
*msg = "Router descriptor was really old.";
routerinfo_free(router);
return ROUTER_WAS_NOT_NEW;
@@ -3569,9 +3582,9 @@ routerlist_remove_old_cached_routers_with_id(time_t now,
n_extra = n - mdpr;
}
- lifespans = tor_malloc_zero(sizeof(struct duration_idx_t)*n);
- rmv = tor_malloc_zero(sizeof(uint8_t)*n);
- must_keep = tor_malloc_zero(sizeof(uint8_t)*n);
+ lifespans = tor_calloc(sizeof(struct duration_idx_t), n);
+ rmv = tor_calloc(sizeof(uint8_t), n);
+ must_keep = tor_calloc(sizeof(uint8_t), n);
/* Set lifespans to contain the lifespan and index of each server. */
/* Set rmv[i-lo]=1 if we're going to remove a server for being too old. */
for (i = lo; i <= hi; ++i) {
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index 6e2f2eaea0..52f2303c7c 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -212,6 +212,9 @@ STATIC int choose_array_element_by_weight(const u64_dbl_t *entries,
int n_entries);
STATIC void scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries,
uint64_t *total_out);
+
+MOCK_DECL(int, router_descriptor_is_older_than, (const routerinfo_t *router,
+ int seconds));
#endif
#endif
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index f990cebd82..250d1cd062 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1900,8 +1900,6 @@ routerstatus_parse_entry_from_string(memarea_t *area,
rs->is_possible_guard = 1;
else if (!strcmp(tok->args[i], "BadExit"))
rs->is_bad_exit = 1;
- else if (!strcmp(tok->args[i], "BadDirectory"))
- rs->is_bad_directory = 1;
else if (!strcmp(tok->args[i], "Authority"))
rs->is_authority = 1;
else if (!strcmp(tok->args[i], "Unnamed") &&
@@ -1918,12 +1916,9 @@ routerstatus_parse_entry_from_string(memarea_t *area,
rs->version_known = 1;
if (strcmpstart(tok->args[0], "Tor ")) {
rs->version_supports_microdesc_cache = 1;
- rs->version_supports_optimistic_data = 1;
} else {
rs->version_supports_microdesc_cache =
tor_version_supports_microdescriptors(tok->args[0]);
- rs->version_supports_optimistic_data =
- tor_version_as_new_as(tok->args[0], "0.2.3.1-alpha");
rs->version_supports_extend2_cells =
tor_version_as_new_as(tok->args[0], "0.2.4.8-alpha");
}
@@ -2048,6 +2043,7 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method)
double Gtotal=0, Mtotal=0, Etotal=0;
const char *casename = NULL;
int valid = 1;
+ (void) consensus_method;
weight_scale = networkstatus_get_weight_scale_param(ns);
Wgg = networkstatus_get_bw_weight(ns, "Wgg", -1);
@@ -2127,12 +2123,8 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method)
// Then, gather G, M, E, D, T to determine case
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
int is_exit = 0;
- if (consensus_method >= MIN_METHOD_TO_CUT_BADEXIT_WEIGHT) {
- /* Bug #2203: Don't count bad exits as exits for balancing */
- is_exit = rs->is_exit && !rs->is_bad_exit;
- } else {
- is_exit = rs->is_exit;
- }
+ /* Bug #2203: Don't count bad exits as exits for balancing */
+ is_exit = rs->is_exit && !rs->is_bad_exit;
if (rs->has_bandwidth) {
T += rs->bandwidth_kb;
if (is_exit && rs->is_possible_guard) {
@@ -3247,8 +3239,8 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
* AF_UNSPEC for '*'. Use policy_expand_unspec() to turn this into a pair
* of AF_INET and AF_INET6 items.
*/
-addr_policy_t *
-router_parse_addr_policy_item_from_string(const char *s, int assume_action)
+MOCK_IMPL(addr_policy_t *,
+router_parse_addr_policy_item_from_string,(const char *s, int assume_action))
{
directory_token_t *tok = NULL;
const char *cp, *eos;
diff --git a/src/or/routerparse.h b/src/or/routerparse.h
index 5d5d9e59ef..fa275c8265 100644
--- a/src/or/routerparse.h
+++ b/src/or/routerparse.h
@@ -37,8 +37,8 @@ routerinfo_t *router_parse_entry_from_string(const char *s, const char *end,
const char *prepend_annotations);
extrainfo_t *extrainfo_parse_entry_from_string(const char *s, const char *end,
int cache_copy, struct digest_ri_map_t *routermap);
-addr_policy_t *router_parse_addr_policy_item_from_string(const char *s,
- int assume_action);
+MOCK_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string,
+ (const char *s, int assume_action));
version_status_t tor_version_is_obsolete(const char *myversion,
const char *versionlist);
int tor_version_supports_microdescriptors(const char *platform);
diff --git a/src/or/routerset.c b/src/or/routerset.c
index 7aee90d6db..e1b8e23742 100644
--- a/src/or/routerset.c
+++ b/src/or/routerset.c
@@ -4,6 +4,8 @@
* Copyright (c) 2007-2013, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+#define ROUTERSET_PRIVATE
+
#include "or.h"
#include "geoip.h"
#include "nodelist.h"
@@ -12,39 +14,6 @@
#include "routerparse.h"
#include "routerset.h"
-/** A routerset specifies constraints on a set of possible routerinfos, based
- * on their names, identities, or addresses. It is optimized for determining
- * whether a router is a member or not, in O(1+P) time, where P is the number
- * of address policy constraints. */
-struct routerset_t {
- /** A list of strings for the elements of the policy. Each string is either
- * a nickname, a hexadecimal identity fingerprint, or an address policy. A
- * router belongs to the set if its nickname OR its identity OR its address
- * matches an entry here. */
- smartlist_t *list;
- /** A map from lowercase nicknames of routers in the set to (void*)1 */
- strmap_t *names;
- /** A map from identity digests routers in the set to (void*)1 */
- digestmap_t *digests;
- /** An address policy for routers in the set. For implementation reasons,
- * a router belongs to the set if it is _rejected_ by this policy. */
- smartlist_t *policies;
-
- /** A human-readable description of what this routerset is for. Used in
- * log messages. */
- char *description;
-
- /** A list of the country codes in this set. */
- smartlist_t *country_names;
- /** Total number of countries we knew about when we built <b>countries</b>.*/
- int n_countries;
- /** Bit array mapping the return value of geoip_get_country() to 1 iff the
- * country is a member of this routerset. Note that we MUST call
- * routerset_refresh_countries() whenever the geoip country list is
- * reloaded. */
- bitarray_t *countries;
-};
-
/** Return a new empty routerset. */
routerset_t *
routerset_new(void)
@@ -60,7 +29,7 @@ routerset_new(void)
/** If <b>c</b> is a country code in the form {cc}, return a newly allocated
* string holding the "cc" part. Else, return NULL. */
-static char *
+STATIC char *
routerset_get_countryname(const char *c)
{
char *country;
@@ -200,7 +169,7 @@ routerset_is_empty(const routerset_t *set)
*
* (If country is -1, then we take the country
* from addr.) */
-static int
+STATIC int
routerset_contains(const routerset_t *set, const tor_addr_t *addr,
uint16_t orport,
const char *nickname, const char *id_digest,
diff --git a/src/or/routerset.h b/src/or/routerset.h
index 8261c7fb09..eafd331b00 100644
--- a/src/or/routerset.h
+++ b/src/or/routerset.h
@@ -39,5 +39,45 @@ char *routerset_to_string(const routerset_t *routerset);
int routerset_equal(const routerset_t *old, const routerset_t *new);
void routerset_free(routerset_t *routerset);
+#ifdef ROUTERSET_PRIVATE
+STATIC char * routerset_get_countryname(const char *c);
+STATIC int routerset_contains(const routerset_t *set, const tor_addr_t *addr,
+ uint16_t orport,
+ const char *nickname, const char *id_digest,
+ country_t country);
+
+/** A routerset specifies constraints on a set of possible routerinfos, based
+ * on their names, identities, or addresses. It is optimized for determining
+ * whether a router is a member or not, in O(1+P) time, where P is the number
+ * of address policy constraints. */
+struct routerset_t {
+ /** A list of strings for the elements of the policy. Each string is either
+ * a nickname, a hexadecimal identity fingerprint, or an address policy. A
+ * router belongs to the set if its nickname OR its identity OR its address
+ * matches an entry here. */
+ smartlist_t *list;
+ /** A map from lowercase nicknames of routers in the set to (void*)1 */
+ strmap_t *names;
+ /** A map from identity digests routers in the set to (void*)1 */
+ digestmap_t *digests;
+ /** An address policy for routers in the set. For implementation reasons,
+ * a router belongs to the set if it is _rejected_ by this policy. */
+ smartlist_t *policies;
+
+ /** A human-readable description of what this routerset is for. Used in
+ * log messages. */
+ char *description;
+
+ /** A list of the country codes in this set. */
+ smartlist_t *country_names;
+ /** Total number of countries we knew about when we built <b>countries</b>.*/
+ int n_countries;
+ /** Bit array mapping the return value of geoip_get_country() to 1 iff the
+ * country is a member of this routerset. Note that we MUST call
+ * routerset_refresh_countries() whenever the geoip country list is
+ * reloaded. */
+ bitarray_t *countries;
+};
+#endif
#endif
diff --git a/src/or/status.c b/src/or/status.c
index afaa9de840..daae1d71c6 100644
--- a/src/or/status.c
+++ b/src/or/status.c
@@ -28,13 +28,7 @@ static void log_accounting(const time_t now, const or_options_t *options);
STATIC int
count_circuits(void)
{
- circuit_t *circ;
- int nr=0;
-
- TOR_LIST_FOREACH(circ, circuit_get_global_list(), head)
- nr++;
-
- return nr;
+ return smartlist_len(circuit_get_global_list());
}
/** Take seconds <b>secs</b> and return a newly allocated human-readable
@@ -151,10 +145,14 @@ log_accounting(const time_t now, const or_options_t *options)
or_state_t *state = get_or_state();
char *acc_rcvd = bytes_to_usage(state->AccountingBytesReadInInterval);
char *acc_sent = bytes_to_usage(state->AccountingBytesWrittenInInterval);
- char *acc_max = bytes_to_usage(options->AccountingMax);
+ uint64_t acc_bytes = options->AccountingMax;
+ char *acc_max;
time_t interval_end = accounting_get_end_time();
char end_buf[ISO_TIME_LEN + 1];
char *remaining = NULL;
+ if (options->AccountingRule == ACCT_SUM)
+ acc_bytes *= 2;
+ acc_max = bytes_to_usage(acc_bytes);
format_local_iso_time(end_buf, interval_end);
remaining = secs_to_uptime(interval_end - now);
diff --git a/src/or/transports.c b/src/or/transports.c
index dc30754162..5c7c0b7130 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -124,6 +124,8 @@ static INLINE void free_execve_args(char **arg);
#define PROTO_SMETHOD_ERROR "SMETHOD-ERROR"
#define PROTO_CMETHODS_DONE "CMETHODS DONE"
#define PROTO_SMETHODS_DONE "SMETHODS DONE"
+#define PROTO_PROXY_DONE "PROXY DONE"
+#define PROTO_PROXY_ERROR "PROXY-ERROR"
/** The first and only supported - at the moment - configuration
protocol version. */
@@ -439,6 +441,17 @@ add_transport_to_proxy(const char *transport, managed_proxy_t *mp)
static int
proxy_needs_restart(const managed_proxy_t *mp)
{
+ int ret = 1;
+ char* proxy_uri;
+
+ /* If the PT proxy config has changed, then all existing pluggable transports
+ * should be restarted.
+ */
+
+ proxy_uri = get_pt_proxy_uri();
+ if (strcmp_opt(proxy_uri, mp->proxy_uri) != 0)
+ goto needs_restart;
+
/* mp->transport_to_launch is populated with the names of the
transports that must be launched *after* the SIGHUP.
mp->transports is populated with the transports that were
@@ -459,10 +472,10 @@ proxy_needs_restart(const managed_proxy_t *mp)
} SMARTLIST_FOREACH_END(t);
- return 0;
-
+ ret = 0;
needs_restart:
- return 1;
+ tor_free(proxy_uri);
+ return ret;
}
/** Managed proxy <b>mp</b> must be restarted. Do all the necessary
@@ -493,6 +506,11 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
smartlist_clear(mp->transports);
+ /* Reset the proxy's HTTPS/SOCKS proxy */
+ tor_free(mp->proxy_uri);
+ mp->proxy_uri = get_pt_proxy_uri();
+ mp->proxy_supported = 0;
+
/* flag it as an infant proxy so that it gets launched on next tick */
mp->conf_state = PT_PROTO_INFANT;
unconfigured_proxies_n++;
@@ -727,12 +745,54 @@ managed_proxy_destroy(managed_proxy_t *mp,
/* free the argv */
free_execve_args(mp->argv);
+ /* free the outgoing proxy URI */
+ tor_free(mp->proxy_uri);
+
tor_process_handle_destroy(mp->process_handle, also_terminate_process);
mp->process_handle = NULL;
tor_free(mp);
}
+/** Convert the tor proxy options to a URI suitable for TOR_PT_PROXY.
+ * Return a newly allocated string containing the URI, or NULL if no
+ * proxy is set. */
+STATIC char *
+get_pt_proxy_uri(void)
+{
+ const or_options_t *options = get_options();
+ char *uri = NULL;
+
+ if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
+ char addr[TOR_ADDR_BUF_LEN+1];
+
+ if (options->Socks4Proxy) {
+ tor_addr_to_str(addr, &options->Socks4ProxyAddr, sizeof(addr), 1);
+ tor_asprintf(&uri, "socks4a://%s:%d", addr, options->Socks4ProxyPort);
+ } else if (options->Socks5Proxy) {
+ tor_addr_to_str(addr, &options->Socks5ProxyAddr, sizeof(addr), 1);
+ if (!options->Socks5ProxyUsername && !options->Socks5ProxyPassword) {
+ tor_asprintf(&uri, "socks5://%s:%d", addr, options->Socks5ProxyPort);
+ } else {
+ tor_asprintf(&uri, "socks5://%s:%s@%s:%d",
+ options->Socks5ProxyUsername,
+ options->Socks5ProxyPassword,
+ addr, options->Socks5ProxyPort);
+ }
+ } else if (options->HTTPSProxy) {
+ tor_addr_to_str(addr, &options->HTTPSProxyAddr, sizeof(addr), 1);
+ if (!options->HTTPSProxyAuthenticator) {
+ tor_asprintf(&uri, "http://%s:%d", addr, options->HTTPSProxyPort);
+ } else {
+ tor_asprintf(&uri, "http://%s@%s:%d", options->HTTPSProxyAuthenticator,
+ addr, options->HTTPSProxyPort);
+ }
+ }
+ }
+
+ return uri;
+}
+
/** Handle a configured or broken managed proxy <b>mp</b>. */
static void
handle_finished_proxy(managed_proxy_t *mp)
@@ -745,6 +805,13 @@ handle_finished_proxy(managed_proxy_t *mp)
managed_proxy_destroy(mp, 0); /* destroy it but don't terminate */
break;
case PT_PROTO_CONFIGURED: /* if configured correctly: */
+ if (mp->proxy_uri && !mp->proxy_supported) {
+ log_warn(LD_CONFIG, "Managed proxy '%s' did not configure the "
+ "specified outgoing proxy and will be terminated.",
+ mp->argv[0]);
+ managed_proxy_destroy(mp, 1); /* annihilate it. */
+ break;
+ }
register_proxy(mp); /* register its transports */
mp->conf_state = PT_PROTO_COMPLETED; /* and mark it as completed. */
break;
@@ -862,6 +929,22 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
goto err;
return;
+ } else if (!strcmpstart(line, PROTO_PROXY_DONE)) {
+ if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
+ goto err;
+
+ if (mp->proxy_uri) {
+ mp->proxy_supported = 1;
+ return;
+ }
+
+ /* No proxy was configured, this should log */
+ } else if (!strcmpstart(line, PROTO_PROXY_ERROR)) {
+ if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
+ goto err;
+
+ parse_proxy_error(line);
+ goto err;
} else if (!strcmpstart(line, SPAWN_ERROR_MESSAGE)) {
/* managed proxy launch failed: parse error message to learn why. */
int retval, child_state, saved_errno;
@@ -1128,6 +1211,21 @@ parse_cmethod_line(const char *line, managed_proxy_t *mp)
return r;
}
+/** Parses an PROXY-ERROR <b>line</b> and warns the user accordingly. */
+STATIC void
+parse_proxy_error(const char *line)
+{
+ /* (Length of the protocol string) plus (a space) and (the first char of
+ the error message) */
+ if (strlen(line) < (strlen(PROTO_PROXY_ERROR) + 2))
+ log_notice(LD_CONFIG, "Managed proxy sent us an %s without an error "
+ "message.", PROTO_PROXY_ERROR);
+
+ log_warn(LD_CONFIG, "Managed proxy failed to configure the "
+ "pluggable transport's outgoing proxy. (%s)",
+ line+strlen(PROTO_PROXY_ERROR)+1);
+}
+
/** Return a newly allocated string that tor should place in
* TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
* manged proxy in <b>mp</b>. Return NULL if no such options are found. */
@@ -1292,6 +1390,14 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
} else {
smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=");
}
+ } else {
+ /* If ClientTransportPlugin has a HTTPS/SOCKS proxy configured, set the
+ * TOR_PT_PROXY line.
+ */
+
+ if (mp->proxy_uri) {
+ smartlist_add_asprintf(envs, "TOR_PT_PROXY=%s", mp->proxy_uri);
+ }
}
SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
@@ -1324,6 +1430,7 @@ managed_proxy_create(const smartlist_t *transport_list,
mp->is_server = is_server;
mp->argv = proxy_argv;
mp->transports = smartlist_new();
+ mp->proxy_uri = get_pt_proxy_uri();
mp->transports_to_launch = smartlist_new();
SMARTLIST_FOREACH(transport_list, const char *, transport,
diff --git a/src/or/transports.h b/src/or/transports.h
index 1365ead006..25fe5a29a9 100644
--- a/src/or/transports.h
+++ b/src/or/transports.h
@@ -81,6 +81,9 @@ typedef struct {
char **argv; /* the cli arguments of this proxy */
int conf_protocol; /* the configuration protocol version used */
+ char *proxy_uri; /* the outgoing proxy in TOR_PT_PROXY URI format */
+ unsigned int proxy_supported : 1; /* the proxy honors TOR_PT_PROXY */
+
int is_server; /* is it a server proxy? */
/* A pointer to the process handle of this managed proxy. */
@@ -112,6 +115,7 @@ STATIC int parse_smethod_line(const char *line, managed_proxy_t *mp);
STATIC int parse_version(const char *line, managed_proxy_t *mp);
STATIC void parse_env_error(const char *line);
+STATIC void parse_proxy_error(const char *line);
STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);
@@ -123,6 +127,8 @@ STATIC managed_proxy_t *managed_proxy_create(const smartlist_t *transport_list,
STATIC int configure_proxy(managed_proxy_t *mp);
+STATIC char* get_pt_proxy_uri(void);
+
#endif
#endif
diff --git a/src/test/bench.c b/src/test/bench.c
index f6c33626f2..1204854b36 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -30,6 +30,7 @@ const char tor_git_revision[] = "";
#include "crypto_curve25519.h"
#include "onion_ntor.h"
#endif
+#include "crypto_ed25519.h"
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
static uint64_t nanostart;
@@ -79,6 +80,9 @@ perftime(void)
#define NANOCOUNT(start,end,iters) \
( ((double)((end)-(start))) / (iters) )
+#define MICROCOUNT(start,end,iters) \
+ ( NANOCOUNT((start), (end), (iters)) / 1000.0 )
+
/** Run AES performance benchmarks. */
static void
bench_aes(void)
@@ -232,6 +236,63 @@ bench_onion_ntor(void)
ntor_handshake_state_free(state);
dimap_free(keymap, NULL);
}
+
+static void
+bench_ed25519(void)
+{
+ uint64_t start, end;
+ const int iters = 1<<12;
+ int i;
+ const uint8_t msg[] = "but leaving, could not tell what they had heard";
+ ed25519_signature_t sig;
+ ed25519_keypair_t kp;
+ curve25519_keypair_t curve_kp;
+ ed25519_public_key_t pubkey_tmp;
+
+ ed25519_secret_key_generate(&kp.seckey, 0);
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
+ }
+ end = perftime();
+ printf("Generate public key: %.2f usec\n",
+ MICROCOUNT(start, end, iters));
+
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ ed25519_sign(&sig, msg, sizeof(msg), &kp);
+ }
+ end = perftime();
+ printf("Sign a short message: %.2f usec\n",
+ MICROCOUNT(start, end, iters));
+
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ ed25519_checksig(&sig, msg, sizeof(msg), &kp.pubkey);
+ }
+ end = perftime();
+ printf("Verify signature: %.2f usec\n",
+ MICROCOUNT(start, end, iters));
+
+ curve25519_keypair_generate(&curve_kp, 0);
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ ed25519_public_key_from_curve25519_public_key(&pubkey_tmp,
+ &curve_kp.pubkey, 1);
+ }
+ end = perftime();
+ printf("Convert public point from curve25519: %.2f usec\n",
+ MICROCOUNT(start, end, iters));
+
+ curve25519_keypair_generate(&curve_kp, 0);
+ start = perftime();
+ for (i = 0; i < iters; ++i) {
+ ed25519_public_blind(&pubkey_tmp, &kp.pubkey, msg);
+ }
+ end = perftime();
+ printf("Blind a public key: %.2f usec\n",
+ MICROCOUNT(start, end, iters));
+}
#endif
static void
@@ -514,6 +575,7 @@ static struct benchmark_t benchmarks[] = {
ENT(onion_TAP),
#ifdef CURVE25519_ENABLED
ENT(onion_ntor),
+ ENT(ed25519),
#endif
ENT(cell_aes),
ENT(cell_ops),
diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py
new file mode 100644
index 0000000000..93dc49ee93
--- /dev/null
+++ b/src/test/ed25519_exts_ref.py
@@ -0,0 +1,234 @@
+#!/usr/bin/python
+# Copyright 2014, The Tor Project, Inc
+# See LICENSE for licensing information
+
+"""
+ Reference implementations for the ed25519 tweaks that Tor uses.
+
+ Includes self-tester and test vector generator.
+"""
+
+import slow_ed25519
+from slow_ed25519 import *
+
+import os
+import random
+import slownacl_curve25519
+import unittest
+import binascii
+import textwrap
+
+#define a synonym that doesn't look like 1
+ell = l
+
+# This replaces expmod above and makes it go a lot faster.
+slow_ed25519.expmod = pow
+
+def curve25519ToEd25519(c, sign):
+ u = decodeint(c)
+ y = ((u - 1) * inv(u + 1)) % q
+ x = xrecover(y)
+ if x & 1 != sign: x = q-x
+ return encodepoint([x,y])
+
+def blindESK(esk, param):
+ h = H("Derive temporary signing key" + param)
+ mult = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
+ s = decodeint(esk[:32])
+ s_prime = (s * mult) % ell
+ k = esk[32:]
+ assert(len(k) == 32)
+ k_prime = H("Derive temporary signing key hash input" + k)[:32]
+ return encodeint(s_prime) + k_prime
+
+def blindPK(pk, param):
+ h = H("Derive temporary signing key" + param)
+ mult = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
+ P = decodepoint(pk)
+ return encodepoint(scalarmult(P, mult))
+
+def expandSK(sk):
+ h = H(sk)
+ a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
+ k = ''.join([h[i] for i in range(b/8,b/4)])
+ assert len(k) == 32
+ return encodeint(a)+k
+
+def publickeyFromESK(h):
+ a = decodeint(h[:32])
+ A = scalarmult(B,a)
+ return encodepoint(A)
+
+def signatureWithESK(m,h,pk):
+ a = decodeint(h[:32])
+ r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m)
+ R = scalarmult(B,r)
+ S = (r + Hint(encodepoint(R) + pk + m) * a) % l
+ return encodepoint(R) + encodeint(S)
+
+def newSK():
+ return os.urandom(32)
+
+# ------------------------------------------------------------
+
+MSG = "This is extremely silly. But it is also incredibly serious business!"
+
+class SelfTest(unittest.TestCase):
+
+ def _testSignatures(self, esk, pk):
+ sig = signatureWithESK(MSG, esk, pk)
+ checkvalid(sig, MSG, pk)
+ bad = False
+ try:
+ checkvalid(sig, MSG*2, pk)
+ bad = True
+ except Exception:
+ pass
+
+ self.failIf(bad)
+
+ def testExpand(self):
+ sk = newSK()
+ pk = publickey(sk)
+ esk = expandSK(sk)
+ sig1 = signature(MSG, sk, pk)
+ sig2 = signatureWithESK(MSG, esk, pk)
+ self.assertEquals(sig1, sig2)
+
+ def testSignatures(self):
+ sk = newSK()
+ esk = expandSK(sk)
+ pk = publickeyFromESK(esk)
+ pk2 = publickey(sk)
+ self.assertEquals(pk, pk2)
+
+ self._testSignatures(esk, pk)
+
+ def testDerivation(self):
+ priv = slownacl_curve25519.Private()
+ pub = priv.get_public()
+
+ ed_pub0 = publickeyFromESK(priv.private)
+ sign = (ord(ed_pub0[31]) & 255) >> 7
+ ed_pub1 = curve25519ToEd25519(pub.public, sign)
+
+ self.assertEquals(ed_pub0, ed_pub1)
+
+ def testBlinding(self):
+ sk = newSK()
+ esk = expandSK(sk)
+ pk = publickeyFromESK(esk)
+ param = os.urandom(32)
+ besk = blindESK(esk, param)
+ bpk = blindPK(pk, param)
+ bpk2 = publickeyFromESK(besk)
+ self.assertEquals(bpk, bpk2)
+
+ self._testSignatures(besk, bpk)
+
+# ------------------------------------------------------------
+
+# From pprint.pprint([ binascii.b2a_hex(os.urandom(32)) for _ in xrange(8) ])
+RAND_INPUTS = [
+ '26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36',
+ 'fba7a5366b5cb98c2667a18783f5cf8f4f8d1a2ce939ad22a6e685edde85128d',
+ '67e3aa7a14fac8445d15e45e38a523481a69ae35513c9e4143eb1c2196729a0e',
+ 'd51385942033a76dc17f089a59e6a5a7fe80d9c526ae8ddd8c3a506b99d3d0a6',
+ '5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb433',
+ 'eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86',
+ '4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d',
+ 'c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b']
+
+# From pprint.pprint([ binascii.b2a_hex(os.urandom(32)) for _ in xrange(8) ])
+BLINDING_PARAMS = [
+ '54a513898b471d1d448a2f3c55c1de2c0ef718c447b04497eeb999ed32027823',
+ '831e9b5325b5d31b7ae6197e9c7a7baf2ec361e08248bce055908971047a2347',
+ 'ac78a1d46faf3bfbbdc5af5f053dc6dc9023ed78236bec1760dadfd0b2603760',
+ 'f9c84dc0ac31571507993df94da1b3d28684a12ad14e67d0a068aba5c53019fc',
+ 'b1fe79d1dec9bc108df69f6612c72812755751f21ecc5af99663b30be8b9081f',
+ '81f1512b63ab5fb5c1711a4ec83d379c420574aedffa8c3368e1c3989a3a0084',
+ '97f45142597c473a4b0e9a12d64561133ad9e1155fe5a9807fe6af8a93557818',
+ '3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0']
+
+PREFIX = "ED25519_"
+
+def writeArray(name, array):
+ print "static const char *{prefix}{name}[] = {{".format(
+ prefix=PREFIX,name=name)
+ for a in array:
+ h = binascii.b2a_hex(a)
+ if len(h) > 70:
+ h1 = h[:70]
+ h2 = h[70:]
+ print ' "{0}"\n "{1}",'.format(h1,h2)
+ else:
+ print ' "{0}",'.format(h)
+ print "};\n"
+
+def comment(text, initial="/**"):
+ print initial
+ print textwrap.fill(text,initial_indent=" * ",subsequent_indent=" * ")
+ print " */"
+
+def makeTestVectors():
+ comment("""Test vectors for our ed25519 implementation and related
+ functions. These were automatically generated by the
+ ed25519_exts_ref.py script.""", initial="/*")
+
+
+ comment("""Secret key seeds used as inputs for the ed25519 test vectors.
+ Randomly generated. """)
+ secretKeys = [ binascii.a2b_hex(r) for r in RAND_INPUTS ]
+ writeArray("SECRET_KEYS", secretKeys)
+
+ comment("""Secret ed25519 keys after expansion from seeds. This is how Tor
+ represents them internally.""")
+ expandedSecretKeys = [ expandSK(sk) for sk in secretKeys ]
+ writeArray("EXPANDED_SECRET_KEYS", expandedSecretKeys)
+
+ comment("""Public keys derived from the above secret keys""")
+ publicKeys = [ publickey(sk) for sk in secretKeys ]
+ writeArray("PUBLIC_KEYS", publicKeys)
+
+ comment("""The curve25519 public keys from which the ed25519 keys can be
+ derived. Used to test our 'derive ed25519 from curve25519'
+ code.""")
+ writeArray("CURVE25519_PUBLIC_KEYS",
+ (slownacl_curve25519.smult_curve25519_base(sk[:32])
+ for sk in expandedSecretKeys))
+
+ comment("""Parameters used for key blinding tests. Randomly generated.""")
+ blindingParams = [ binascii.a2b_hex(r) for r in BLINDING_PARAMS ]
+ writeArray("BLINDING_PARAMS", blindingParams)
+
+ comment("""Blinded secret keys for testing key blinding. The nth blinded
+ key corresponds to the nth secret key blidned with the nth
+ blinding parameter.""")
+ writeArray("BLINDED_SECRET_KEYS",
+ (blindESK(expandSK(sk), bp)
+ for sk,bp in zip(secretKeys,blindingParams)))
+
+ comment("""Blinded public keys for testing key blinding. The nth blinded
+ key corresponds to the nth public key blidned with the nth
+ blinding parameter.""")
+ writeArray("BLINDED_PUBLIC_KEYS",
+ (blindPK(pk, bp) for pk,bp in zip(publicKeys,blindingParams)))
+
+ comment("""Signatures of the public keys, made with their corresponding
+ secret keys.""")
+ writeArray("SELF_SIGNATURES",
+ (signature(pk, sk, pk) for pk,sk in zip(publicKeys,secretKeys)))
+
+
+
+if __name__ == '__main__':
+ import sys
+ if len(sys.argv) == 1 or sys.argv[1] not in ("SelfTest", "MakeVectors"):
+ print "You should specify one of 'SelfTest' or 'MakeVectors'"
+ sys.exit(1)
+ if sys.argv[1] == 'SelfTest':
+ unittest.main()
+ else:
+ makeTestVectors()
+
+
diff --git a/src/test/ed25519_vectors.inc b/src/test/ed25519_vectors.inc
new file mode 100644
index 0000000000..760bafb971
--- /dev/null
+++ b/src/test/ed25519_vectors.inc
@@ -0,0 +1,150 @@
+/*
+ * Test vectors for our ed25519 implementation and related
+ * functions. These were automatically generated by the
+ * ed25519_exts_ref.py script.
+ */
+/**
+ * Secret key seeds used as inputs for the ed25519 test vectors.
+ * Randomly generated.
+ */
+static const char *ED25519_SECRET_KEYS[] = {
+ "26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36",
+ "fba7a5366b5cb98c2667a18783f5cf8f4f8d1a2ce939ad22a6e685edde85128d",
+ "67e3aa7a14fac8445d15e45e38a523481a69ae35513c9e4143eb1c2196729a0e",
+ "d51385942033a76dc17f089a59e6a5a7fe80d9c526ae8ddd8c3a506b99d3d0a6",
+ "5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb433",
+ "eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86",
+ "4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d",
+ "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b",
+};
+
+/**
+ * Secret ed25519 keys after expansion from seeds. This is how Tor
+ * represents them internally.
+ */
+static const char *ED25519_EXPANDED_SECRET_KEYS[] = {
+ "c0a4de23cc64392d85aa1da82b3defddbea946d13bb053bf8489fa9296281f495022f1"
+ "f7ec0dcf52f07d4c7965c4eaed121d5d88d0a8ff546b06116a20e97755",
+ "18a8a69a06790dac778e882f7e868baacfa12521a5c058f5194f3a729184514a2a656f"
+ "e7799c3e41f43d756da8d9cd47a061316cfe6147e23ea2f90d1ca45f30",
+ "58d84f8862d2ecfa30eb491a81c36d05b574310ea69dae18ecb57e992a896656b98218"
+ "7ee96c15bf4caeeab2d0b0ae4cd0b8d17470fc7efa98bb26428f4ef36d",
+ "50702d20b3550c6e16033db5ad4fba16436f1ecc7485be6af62b0732ceb5d173c47ccd"
+ "9d044b6ea99dd99256adcc9c62191be194e7cb1a5b58ddcec85d876a2b",
+ "7077464c864c2ed5ed21c9916dc3b3ba6256f8b742fec67658d8d233dadc8d5a7a82c3"
+ "71083cc86892c2c8782dda2a09b6baf016aec51b689183ae59ce932ff2",
+ "8883c1387a6c86fc0bd7b9f157b4e4cd83f6885bf55e2706d2235d4527a2f05311a359"
+ "5953282e436df0349e1bb313a19b3ddbf7a7b91ecce8a2c34abadb38b3",
+ "186791ac8d03a3ac8efed6ac360467edd5a3bed2d02b3be713ddd5be53b3287ee37436"
+ "e5fd7ac43794394507ad440ecfdf59c4c255f19b768a273109e06d7d8e",
+ "b003077c1e52a62308eef7950b2d532e1d4a7eea50ad22d8ac11b892851f1c40ffb9c9"
+ "ff8dcd0c6c233f665a2e176324d92416bfcfcd1f787424c0c667452d86",
+};
+
+/**
+ * Public keys derived from the above secret keys
+ */
+static const char *ED25519_PUBLIC_KEYS[] = {
+ "c2247870536a192d142d056abefca68d6193158e7c1a59c1654c954eccaff894",
+ "1519a3b15816a1aafab0b213892026ebf5c0dc232c58b21088d88cb90e9b940d",
+ "081faa81992e360ea22c06af1aba096e7a73f1c665bc8b3e4e531c46455fd1dd",
+ "73cfa1189a723aad7966137cbffa35140bb40d7e16eae4c40b79b5f0360dd65a",
+ "66c1a77104d86461b6f98f73acf3cd229c80624495d2d74d6fda1e940080a96b",
+ "d21c294db0e64cb2d8976625786ede1d9754186ae8197a64d72f68c792eecc19",
+ "c4d58b4cf85a348ff3d410dd936fa460c4f18da962c01b1963792b9dcc8a6ea6",
+ "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4a",
+};
+
+/**
+ * The curve25519 public keys from which the ed25519 keys can be
+ * derived. Used to test our 'derive ed25519 from curve25519'
+ * code.
+ */
+static const char *ED25519_CURVE25519_PUBLIC_KEYS[] = {
+ "17ba77846e04c7ee5ca17cade774ac1884408f9701f439d4df32cbd8736c6a1f",
+ "022be2124bc1899a78ba2b4167d191af3b59cadf94f0382bc31ce183a117f161",
+ "bf4fd38ef22f718f03c0a12ba5127bd1e3afd494793753f519728b29cc577571",
+ "56c493e490261cef31633efd2461d2b896908e90459e4eecde950a895aef681d",
+ "089675a3e8ff2a7d8b2844a79269c95b7f97a4b8b5ea0cbeec669c6f2dea9b39",
+ "59e20dcb691c4a345fe86c8a79ac817e5b514d84bbf0512a842a08e43f7f087e",
+ "9e43b820b320eda35f66f122c155b2bf8e2192c468617b7115bf067d19e08369",
+ "861f33296cb57f8f01e4a5e8a7e5d5d7043a6247586ab36dea8a1a3c4403ee30",
+};
+
+/**
+ * Parameters used for key blinding tests. Randomly generated.
+ */
+static const char *ED25519_BLINDING_PARAMS[] = {
+ "54a513898b471d1d448a2f3c55c1de2c0ef718c447b04497eeb999ed32027823",
+ "831e9b5325b5d31b7ae6197e9c7a7baf2ec361e08248bce055908971047a2347",
+ "ac78a1d46faf3bfbbdc5af5f053dc6dc9023ed78236bec1760dadfd0b2603760",
+ "f9c84dc0ac31571507993df94da1b3d28684a12ad14e67d0a068aba5c53019fc",
+ "b1fe79d1dec9bc108df69f6612c72812755751f21ecc5af99663b30be8b9081f",
+ "81f1512b63ab5fb5c1711a4ec83d379c420574aedffa8c3368e1c3989a3a0084",
+ "97f45142597c473a4b0e9a12d64561133ad9e1155fe5a9807fe6af8a93557818",
+ "3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0",
+};
+
+/**
+ * Blinded secret keys for testing key blinding. The nth blinded
+ * key corresponds to the nth secret key blidned with the nth
+ * blinding parameter.
+ */
+static const char *ED25519_BLINDED_SECRET_KEYS[] = {
+ "014e83abadb2ca9a27e0ffe23920333d817729f48700e97656ec2823d694050e171d43"
+ "f24e3f53e70ec7ac280044ac77d4942dee5d6807118a59bdf3ee647e89",
+ "fad8cca0b4335847795288b1452508752b253e64e6c7c78d4a02dbbd7d46aa0eb8ceff"
+ "20dfcf53eb52b891fc078c934efbf0353af7242e7dc51bb32a093afa29",
+ "116eb0ae0a4a91763365bdf86db427b00862db448487808788cc339ac10e5e089217f5"
+ "2e92797462bd890fc274672e05c98f2c82970d640084781334aae0f940",
+ "bd1fbb0ee5acddc4adbcf5f33e95d9445f40326ce579fdd764a24483a9ccb20f509ece"
+ "e77082ce088f7c19d5a00e955eeef8df6fa41686abc1030c2d76807733",
+ "237f5345cefe8573ce9fa7e216381a1172796c9e3f70668ab503b1352952530fb57b95"
+ "a440570659a440a3e4771465022a8e67af86bdf2d0990c54e7bb87ff9a",
+ "ba8ff23bc4ad2b739e1ccffc9fbc7837053ea81cdfdb15073f56411cfbae1d0ec492fc"
+ "87d5ec2a1b185ca5a40541fdef0b1e128fd5c2380c888bfa924711bcab",
+ "0fa68f969de038c7a90a4a74ee6167c77582006f2dedecc1956501ba6b6fb10391b476"
+ "8f8e556d78f4bdcb9a13b6f6066fe81d3134ae965dc48cd0785b3af2b8",
+ "deaa3456d1c21944d5dcd361a646858c6cf9336b0a6851d925717eb1ae186902053d9c"
+ "00c81e1331c06ab50087be8cfc7dc11691b132614474f1aa9c2503cccd",
+};
+
+/**
+ * Blinded public keys for testing key blinding. The nth blinded
+ * key corresponds to the nth public key blidned with the nth
+ * blinding parameter.
+ */
+static const char *ED25519_BLINDED_PUBLIC_KEYS[] = {
+ "722d6da6348e618967ef782e71061e27163a8b35f21856475d9d2023f65b6495",
+ "1dffa0586da6cbfcff2024eedf4fc6c818242d9a82dbbe635d6da1b975a1160d",
+ "5ed81f98fed5a6acda4ea6da2c34fab0ab359d950c510c256473f1f33ff438b4",
+ "6e6f92a54fb282120c46d9603df41135f025bc1f58f283809d04be96aeb04040",
+ "cda236f28edc4c7e02d18007b8dab49d669265b0f7aefb1824d7cc8e73a2cd63",
+ "367b03b17b67ca7329b89a520bdab91782402a41cd67264e34b5541a4b3f875b",
+ "8d486b03ac4e3b486b7a1d563706c7fdac75aee789a7cf6f22789eedeff61a31",
+ "9f297ff0aa2ceda91c5ab1b6446f12533d145940de6d850dc323417afde0cb78",
+};
+
+/**
+ * Signatures of the public keys, made with their corresponding
+ * secret keys.
+ */
+static const char *ED25519_SELF_SIGNATURES[] = {
+ "d23188eac3773a316d46006fa59c095060be8b1a23582a0dd99002a82a0662bd246d84"
+ "49e172e04c5f46ac0d1404cebe4aabd8a75a1457aa06cae41f3334f104",
+ "3a785ac1201c97ee5f6f0d99323960d5f264c7825e61aa7cc81262f15bef75eb4fa572"
+ "3add9b9d45b12311b6d403eb3ac79ff8e4e631fc3cd51e4ad2185b200b",
+ "cf431fd0416bfbd20c9d95ef9b723e2acddffb33900edc72195dea95965d52d888d30b"
+ "7b8a677c0bd8ae1417b1e1a0ec6700deadd5d8b54b6689275e04a04509",
+ "2375380cd72d1a6c642aeddff862be8a5804b916acb72c02d9ed052c1561881aa658a5"
+ "af856fcd6d43113e42f698cd6687c99efeef7f2ce045824440d26c5d00",
+ "2385a472f599ca965bbe4d610e391cdeabeba9c336694b0d6249e551458280be122c24"
+ "41dd9746a81bbfb9cd619364bab0df37ff4ceb7aefd24469c39d3bc508",
+ "e500cd0b8cfff35442f88008d894f3a2fa26ef7d3a0ca5714ae0d3e2d40caae58ba7cd"
+ "f69dd126994dad6be536fcda846d89dd8138d1683cc144c8853dce7607",
+ "d187b9e334b0050154de10bf69b3e4208a584e1a65015ec28b14bcc252cf84b8baa9c9"
+ "4867daa60f2a82d09ba9652d41e8dde292b624afc8d2c26441b95e3c0e",
+ "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079c9afe0"
+ "afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60d",
+};
+
diff --git a/src/test/include.am b/src/test/include.am
index fba439a616..4020ac4190 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -28,11 +28,13 @@ src_test_test_SOURCES = \
src/test/test_cell_queue.c \
src/test/test_data.c \
src/test/test_dir.c \
+ src/test/test_entrynodes.c \
src/test/test_extorport.c \
src/test/test_introduce.c \
src/test/test_logging.c \
src/test/test_microdesc.c \
src/test/test_oom.c \
+ src/test/test_accounting.c \
src/test/test_options.c \
src/test/test_pt.c \
src/test/test_relaycell.c \
@@ -45,6 +47,7 @@ src_test_test_SOURCES = \
src/test/test_nodelist.c \
src/test/test_policy.c \
src/test/test_status.c \
+ src/test/test_routerset.c \
src/ext/tinytest.c
src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
@@ -58,7 +61,7 @@ src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
@TOR_LDFLAGS_libevent@
src_test_test_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \
src/common/libor-crypto-testing.a $(LIBDONNA) \
- src/common/libor-event-testing.a \
+ src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
@@ -71,7 +74,9 @@ src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
noinst_HEADERS+= \
- src/test/test.h
+ src/test/test.h \
+ src/test/test_descriptors.inc \
+ src/test/ed25519_vectors.inc
if CURVE25519_ENABLED
noinst_PROGRAMS+= src/test/test-ntor-cl
diff --git a/src/test/slow_ed25519.py b/src/test/slow_ed25519.py
new file mode 100644
index 0000000000..f44708b200
--- /dev/null
+++ b/src/test/slow_ed25519.py
@@ -0,0 +1,115 @@
+# This is the ed25519 implementation from
+# http://ed25519.cr.yp.to/python/ed25519.py .
+# It is in the public domain.
+#
+# It isn't constant-time. Don't use it except for testing. Also, see
+# warnings about how very slow it is. Only use this for generating
+# test vectors, I'd suggest.
+#
+# Don't edit this file. Mess with ed25519_ref.py
+
+import hashlib
+
+b = 256
+q = 2**255 - 19
+l = 2**252 + 27742317777372353535851937790883648493
+
+def H(m):
+ return hashlib.sha512(m).digest()
+
+def expmod(b,e,m):
+ if e == 0: return 1
+ t = expmod(b,e/2,m)**2 % m
+ if e & 1: t = (t*b) % m
+ return t
+
+def inv(x):
+ return expmod(x,q-2,q)
+
+d = -121665 * inv(121666)
+I = expmod(2,(q-1)/4,q)
+
+def xrecover(y):
+ xx = (y*y-1) * inv(d*y*y+1)
+ x = expmod(xx,(q+3)/8,q)
+ if (x*x - xx) % q != 0: x = (x*I) % q
+ if x % 2 != 0: x = q-x
+ return x
+
+By = 4 * inv(5)
+Bx = xrecover(By)
+B = [Bx % q,By % q]
+
+def edwards(P,Q):
+ x1 = P[0]
+ y1 = P[1]
+ x2 = Q[0]
+ y2 = Q[1]
+ x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2)
+ y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2)
+ return [x3 % q,y3 % q]
+
+def scalarmult(P,e):
+ if e == 0: return [0,1]
+ Q = scalarmult(P,e/2)
+ Q = edwards(Q,Q)
+ if e & 1: Q = edwards(Q,P)
+ return Q
+
+def encodeint(y):
+ bits = [(y >> i) & 1 for i in range(b)]
+ return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)])
+
+def encodepoint(P):
+ x = P[0]
+ y = P[1]
+ bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1]
+ return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)])
+
+def bit(h,i):
+ return (ord(h[i/8]) >> (i%8)) & 1
+
+def publickey(sk):
+ h = H(sk)
+ a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
+ A = scalarmult(B,a)
+ return encodepoint(A)
+
+def Hint(m):
+ h = H(m)
+ return sum(2**i * bit(h,i) for i in range(2*b))
+
+def signature(m,sk,pk):
+ h = H(sk)
+ a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
+ r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m)
+ R = scalarmult(B,r)
+ S = (r + Hint(encodepoint(R) + pk + m) * a) % l
+ return encodepoint(R) + encodeint(S)
+
+def isoncurve(P):
+ x = P[0]
+ y = P[1]
+ return (-x*x + y*y - 1 - d*x*x*y*y) % q == 0
+
+def decodeint(s):
+ return sum(2**i * bit(s,i) for i in range(0,b))
+
+def decodepoint(s):
+ y = sum(2**i * bit(s,i) for i in range(0,b-1))
+ x = xrecover(y)
+ if x & 1 != bit(s,b-1): x = q-x
+ P = [x,y]
+ if not isoncurve(P): raise Exception("decoding point that is not on curve")
+ return P
+
+def checkvalid(s,m,pk):
+ if len(s) != b/4: raise Exception("signature length is wrong")
+ if len(pk) != b/8: raise Exception("public-key length is wrong")
+ R = decodepoint(s[0:b/8])
+ A = decodepoint(pk)
+ S = decodeint(s[b/8:b/4])
+ h = Hint(encodepoint(R) + pk + m)
+ if scalarmult(B,S) != edwards(R,scalarmult(A,h)):
+ raise Exception("signature does not pass verification")
+
diff --git a/src/test/test.c b/src/test/test.c
index 8bce9c91f4..d2813ed42a 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -43,6 +43,7 @@ long int lround(double x);
double fabs(double x);
#include "or.h"
+#include "backtrace.h"
#include "buffers.h"
#include "circuitlist.h"
#include "circuitstats.h"
@@ -106,11 +107,18 @@ setup_directory(void)
{
char buf[MAX_PATH];
const char *tmp = buf;
+ const char *extra_backslash = "";
/* If this fails, we're probably screwed anyway */
if (!GetTempPathA(sizeof(buf),buf))
- tmp = "c:\\windows\\temp";
+ tmp = "c:\\windows\\temp\\";
+ if (strcmpend(tmp, "\\")) {
+ /* According to MSDN, it should be impossible for GetTempPath to give us
+ * an answer that doesn't end with \. But let's make sure. */
+ extra_backslash = "\\";
+ }
tor_snprintf(temp_dir, sizeof(temp_dir),
- "%s\\tor_test_%d_%s", tmp, (int)getpid(), rnd32);
+ "%s%stor_test_%d_%s", tmp, extra_backslash,
+ (int)getpid(), rnd32);
r = mkdir(temp_dir);
}
#else
@@ -184,7 +192,7 @@ remove_directory(void)
#undef CACHE_GENERATED_KEYS
static crypto_pk_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
-#define N_PREGEN_KEYS ((int)(sizeof(pregen_keys)/sizeof(pregen_keys[0])))
+#define N_PREGEN_KEYS ARRAY_LENGTH(pregen_keys)
/** Generate and return a new keypair for use in unit tests. If we're using
* the key cache optimization, we might reuse keys: we only guarantee that
@@ -224,7 +232,7 @@ free_pregenerated_keys(void)
/** Run unit tests for the onion handshake code. */
static void
-test_onion_handshake(void)
+test_onion_handshake(void *arg)
{
/* client-side */
crypto_dh_t *c_dh = NULL;
@@ -237,12 +245,13 @@ test_onion_handshake(void)
/* shared */
crypto_pk_t *pk = NULL, *pk2 = NULL;
+ (void)arg;
pk = pk_generate(0);
pk2 = pk_generate(1);
/* client handshake 1. */
memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN);
- test_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
+ tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
for (i = 1; i <= 3; ++i) {
crypto_pk_t *k1, *k2;
@@ -259,16 +268,16 @@ test_onion_handshake(void)
memset(s_buf, 0, TAP_ONIONSKIN_REPLY_LEN);
memset(s_keys, 0, 40);
- test_assert(! onion_skin_TAP_server_handshake(c_buf, k1, k2,
+ tt_assert(! onion_skin_TAP_server_handshake(c_buf, k1, k2,
s_buf, s_keys, 40));
/* client handshake 2 */
memset(c_keys, 0, 40);
- test_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
+ tt_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
- test_memeq(c_keys, s_keys, 40);
+ tt_mem_op(c_keys,==, s_keys, 40);
memset(s_buf, 0, 40);
- test_memneq(c_keys, s_buf, 40);
+ tt_mem_op(c_keys,!=, s_buf, 40);
}
done:
crypto_dh_free(c_dh);
@@ -315,7 +324,7 @@ test_bad_onion_handshake(void *arg)
/* client handshake 1: do it straight. */
memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN);
- test_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
+ tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
/* Server: Case 3: we just don't have the right key. */
tt_int_op(-1, ==,
@@ -343,7 +352,7 @@ test_bad_onion_handshake(void *arg)
/* Let the client finish; make sure it can. */
tt_int_op(0, ==,
onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
- test_memeq(s_keys, c_keys, 40);
+ tt_mem_op(s_keys,==, c_keys, 40);
/* Client: Case 2: The server sent back a degenerate DH. */
memset(s_buf, 0, sizeof(s_buf));
@@ -400,9 +409,9 @@ test_ntor_handshake(void *arg)
tt_int_op(0, ==, onion_skin_ntor_client_handshake(c_state, s_buf,
c_keys, 400));
- test_memeq(c_keys, s_keys, 400);
+ tt_mem_op(c_keys,==, s_keys, 400);
memset(s_buf, 0, 40);
- test_memneq(c_keys, s_buf, 40);
+ tt_mem_op(c_keys,!=, s_buf, 40);
done:
ntor_handshake_state_free(c_state);
@@ -412,7 +421,7 @@ test_ntor_handshake(void *arg)
/** Run unit tests for the onion queues. */
static void
-test_onion_queues(void)
+test_onion_queues(void *arg)
{
uint8_t buf1[TAP_ONIONSKIN_CHALLENGE_LEN] = {0};
uint8_t buf2[NTOR_ONIONSKIN_LEN] = {0};
@@ -423,6 +432,7 @@ test_onion_queues(void)
create_cell_t *onionskin = NULL, *create2_ptr;
create_cell_t *create1 = tor_malloc_zero(sizeof(create_cell_t));
create_cell_t *create2 = tor_malloc_zero(sizeof(create_cell_t));
+ (void)arg;
create2_ptr = create2; /* remember, but do not free */
create_cell_init(create1, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP,
@@ -430,24 +440,24 @@ test_onion_queues(void)
create_cell_init(create2, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR,
NTOR_ONIONSKIN_LEN, buf2);
- test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
- test_eq(0, onion_pending_add(circ1, create1));
+ tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
+ tt_int_op(0,==, onion_pending_add(circ1, create1));
create1 = NULL;
- test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
+ tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
- test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
- test_eq(0, onion_pending_add(circ2, create2));
+ tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
+ tt_int_op(0,==, onion_pending_add(circ2, create2));
create2 = NULL;
- test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
+ tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
- test_eq_ptr(circ2, onion_next_task(&onionskin));
- test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
- test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
+ tt_ptr_op(circ2,==, onion_next_task(&onionskin));
+ tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
+ tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
tt_ptr_op(onionskin, ==, create2_ptr);
clear_pending_onions();
- test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
- test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
+ tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
+ tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
done:
circuit_free(TO_CIRCUIT(circ1));
@@ -458,7 +468,7 @@ test_onion_queues(void)
}
static void
-test_circuit_timeout(void)
+test_circuit_timeout(void *arg)
{
/* Plan:
* 1. Generate 1000 samples
@@ -476,6 +486,7 @@ test_circuit_timeout(void)
or_state_t *state=NULL;
int i, runs;
double close_ms;
+ (void)arg;
circuit_build_times_init(&initial);
circuit_build_times_init(&estimate);
circuit_build_times_init(&final);
@@ -510,11 +521,11 @@ test_circuit_timeout(void)
} while (fabs(circuit_build_times_cdf(&initial, timeout0) -
circuit_build_times_cdf(&initial, timeout1)) > 0.02);
- test_assert(estimate.total_build_times <= CBT_NCIRCUITS_TO_OBSERVE);
+ tt_assert(estimate.total_build_times <= CBT_NCIRCUITS_TO_OBSERVE);
circuit_build_times_update_state(&estimate, state);
circuit_build_times_free_timeouts(&final);
- test_assert(circuit_build_times_parse_state(&final, state) == 0);
+ tt_assert(circuit_build_times_parse_state(&final, state) == 0);
circuit_build_times_update_alpha(&final);
timeout2 = circuit_build_times_calculate_timeout(&final,
@@ -524,7 +535,7 @@ test_circuit_timeout(void)
log_notice(LD_CIRC, "Timeout2 is %f, Xm is %d", timeout2, final.Xm);
/* 5% here because some accuracy is lost due to histogram conversion */
- test_assert(fabs(circuit_build_times_cdf(&initial, timeout0) -
+ tt_assert(fabs(circuit_build_times_cdf(&initial, timeout0) -
circuit_build_times_cdf(&initial, timeout2)) < 0.05);
for (runs = 0; runs < 50; runs++) {
@@ -547,8 +558,8 @@ test_circuit_timeout(void)
CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
}
- test_assert(!circuit_build_times_network_check_changed(&estimate));
- test_assert(!circuit_build_times_network_check_changed(&final));
+ tt_assert(!circuit_build_times_network_check_changed(&estimate));
+ tt_assert(!circuit_build_times_network_check_changed(&final));
/* Reset liveness to be non-live */
final.liveness.network_last_live = 0;
@@ -557,27 +568,27 @@ test_circuit_timeout(void)
build_times_idx = estimate.build_times_idx;
total_build_times = estimate.total_build_times;
- test_assert(circuit_build_times_network_check_live(&estimate));
- test_assert(circuit_build_times_network_check_live(&final));
+ tt_assert(circuit_build_times_network_check_live(&estimate));
+ tt_assert(circuit_build_times_network_check_live(&final));
circuit_build_times_count_close(&estimate, 0,
(time_t)(approx_time()-estimate.close_ms/1000.0-1));
circuit_build_times_count_close(&final, 0,
(time_t)(approx_time()-final.close_ms/1000.0-1));
- test_assert(!circuit_build_times_network_check_live(&estimate));
- test_assert(!circuit_build_times_network_check_live(&final));
+ tt_assert(!circuit_build_times_network_check_live(&estimate));
+ tt_assert(!circuit_build_times_network_check_live(&final));
log_info(LD_CIRC, "idx: %d %d, tot: %d %d",
build_times_idx, estimate.build_times_idx,
total_build_times, estimate.total_build_times);
/* Check rollback index. Should match top of loop. */
- test_assert(build_times_idx == estimate.build_times_idx);
+ tt_assert(build_times_idx == estimate.build_times_idx);
// This can fail if estimate.total_build_times == 1000, because
// in that case, rewind actually causes us to lose timeouts
if (total_build_times != CBT_NCIRCUITS_TO_OBSERVE)
- test_assert(total_build_times == estimate.total_build_times);
+ tt_assert(total_build_times == estimate.total_build_times);
/* Now simulate that the network has become live and we need
* a change */
@@ -592,12 +603,12 @@ test_circuit_timeout(void)
}
}
- test_assert(estimate.liveness.after_firsthop_idx == 0);
- test_assert(final.liveness.after_firsthop_idx ==
+ tt_assert(estimate.liveness.after_firsthop_idx == 0);
+ tt_assert(final.liveness.after_firsthop_idx ==
CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1);
- test_assert(circuit_build_times_network_check_live(&estimate));
- test_assert(circuit_build_times_network_check_live(&final));
+ tt_assert(circuit_build_times_network_check_live(&estimate));
+ tt_assert(circuit_build_times_network_check_live(&final));
circuit_build_times_count_timeout(&final, 1);
}
@@ -611,7 +622,7 @@ test_circuit_timeout(void)
/** Test encoding and parsing of rendezvous service descriptors. */
static void
-test_rend_fns(void)
+test_rend_fns(void *arg)
{
rend_service_descriptor_t *generated = NULL, *parsed = NULL;
char service_id[DIGEST_LEN];
@@ -634,16 +645,17 @@ test_rend_fns(void)
char address6[] = "foo.bar.abcdefghijklmnop.onion";
char address7[] = ".abcdefghijklmnop.onion";
- test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
- test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
- test_streq(address2, "aaaaaaaaaaaaaaaa");
- test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
- test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
- test_assert(ONION_HOSTNAME == parse_extended_hostname(address5));
- test_streq(address5, "abcdefghijklmnop");
- test_assert(ONION_HOSTNAME == parse_extended_hostname(address6));
- test_streq(address6, "abcdefghijklmnop");
- test_assert(BAD_HOSTNAME == parse_extended_hostname(address7));
+ (void)arg;
+ tt_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
+ tt_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
+ tt_str_op(address2,==, "aaaaaaaaaaaaaaaa");
+ tt_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
+ tt_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
+ tt_assert(ONION_HOSTNAME == parse_extended_hostname(address5));
+ tt_str_op(address5,==, "abcdefghijklmnop");
+ tt_assert(ONION_HOSTNAME == parse_extended_hostname(address6));
+ tt_str_op(address6,==, "abcdefghijklmnop");
+ tt_assert(BAD_HOSTNAME == parse_extended_hostname(address7));
pk1 = pk_generate(0);
pk2 = pk_generate(1);
@@ -676,40 +688,41 @@ test_rend_fns(void)
intro->intro_key = crypto_pk_dup_key(pk2);
smartlist_add(generated->intro_nodes, intro);
}
- test_assert(rend_encode_v2_descriptors(descs, generated, now, 0,
+ tt_assert(rend_encode_v2_descriptors(descs, generated, now, 0,
REND_NO_AUTH, NULL, NULL) > 0);
- test_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32,
+ tt_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32,
NULL, now, 0) == 0);
- test_memeq(((rend_encoded_v2_service_descriptor_t *)
- smartlist_get(descs, 0))->desc_id, computed_desc_id, DIGEST_LEN);
- test_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id,
+ tt_mem_op(((rend_encoded_v2_service_descriptor_t *)
+ smartlist_get(descs, 0))->desc_id, ==,
+ computed_desc_id, DIGEST_LEN);
+ tt_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id,
&intro_points_encrypted,
&intro_points_size,
&encoded_size,
&next_desc,
((rend_encoded_v2_service_descriptor_t *)
smartlist_get(descs, 0))->desc_str) == 0);
- test_assert(parsed);
- test_memeq(((rend_encoded_v2_service_descriptor_t *)
- smartlist_get(descs, 0))->desc_id, parsed_desc_id, DIGEST_LEN);
- test_eq(rend_parse_introduction_points(parsed, intro_points_encrypted,
- intro_points_size), 3);
- test_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk));
- test_eq(parsed->timestamp, now);
- test_eq(parsed->version, 2);
- test_eq(parsed->protocols, 42);
- test_eq(smartlist_len(parsed->intro_nodes), 3);
+ tt_assert(parsed);
+ tt_mem_op(((rend_encoded_v2_service_descriptor_t *)
+ smartlist_get(descs, 0))->desc_id,==, parsed_desc_id, DIGEST_LEN);
+ tt_int_op(rend_parse_introduction_points(parsed, intro_points_encrypted,
+ intro_points_size),==, 3);
+ tt_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk));
+ tt_int_op(parsed->timestamp,==, now);
+ tt_int_op(parsed->version,==, 2);
+ tt_int_op(parsed->protocols,==, 42);
+ tt_int_op(smartlist_len(parsed->intro_nodes),==, 3);
for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) {
rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i),
*gen_intro = smartlist_get(generated->intro_nodes, i);
extend_info_t *par_info = par_intro->extend_info;
extend_info_t *gen_info = gen_intro->extend_info;
- test_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key));
- test_memeq(gen_info->identity_digest, par_info->identity_digest,
+ tt_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key));
+ tt_mem_op(gen_info->identity_digest,==, par_info->identity_digest,
DIGEST_LEN);
- test_streq(gen_info->nickname, par_info->nickname);
- test_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
- test_eq(gen_info->port, par_info->port);
+ tt_str_op(gen_info->nickname,==, par_info->nickname);
+ tt_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
+ tt_int_op(gen_info->port,==, par_info->port);
}
rend_service_descriptor_free(parsed);
@@ -753,17 +766,17 @@ test_rend_fns(void)
} while (0)
#define CHECK_COUNTRY(country, val) do { \
/* test ipv4 country lookup */ \
- test_streq(country, \
+ tt_str_op(country, ==, \
geoip_get_country_name(geoip_get_country_by_ipv4(val))); \
/* test ipv6 country lookup */ \
SET_TEST_IPV6(val); \
- test_streq(country, \
+ tt_str_op(country, ==, \
geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \
} while (0)
/** Run unit tests for GeoIP code. */
static void
-test_geoip(void)
+test_geoip(void *arg)
{
int i, j;
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
@@ -817,23 +830,24 @@ test_geoip(void)
/* Populate the DB a bit. Add these in order, since we can't do the final
* 'sort' step. These aren't very good IP addresses, but they're perfectly
* fine uint32_t values. */
- test_eq(0, geoip_parse_entry("10,50,AB", AF_INET));
- test_eq(0, geoip_parse_entry("52,90,XY", AF_INET));
- test_eq(0, geoip_parse_entry("95,100,AB", AF_INET));
- test_eq(0, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
- test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
- test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
+ (void)arg;
+ tt_int_op(0,==, geoip_parse_entry("10,50,AB", AF_INET));
+ tt_int_op(0,==, geoip_parse_entry("52,90,XY", AF_INET));
+ tt_int_op(0,==, geoip_parse_entry("95,100,AB", AF_INET));
+ tt_int_op(0,==, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
+ tt_int_op(0,==, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
+ tt_int_op(0,==, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
/* Populate the IPv6 DB equivalently with fake IPs in the same range */
- test_eq(0, geoip_parse_entry("::a,::32,AB", AF_INET6));
- test_eq(0, geoip_parse_entry("::34,::5a,XY", AF_INET6));
- test_eq(0, geoip_parse_entry("::5f,::64,AB", AF_INET6));
- test_eq(0, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
- test_eq(0, geoip_parse_entry("::96,::be,XY", AF_INET6));
- test_eq(0, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
+ tt_int_op(0,==, geoip_parse_entry("::a,::32,AB", AF_INET6));
+ tt_int_op(0,==, geoip_parse_entry("::34,::5a,XY", AF_INET6));
+ tt_int_op(0,==, geoip_parse_entry("::5f,::64,AB", AF_INET6));
+ tt_int_op(0,==, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
+ tt_int_op(0,==, geoip_parse_entry("::96,::be,XY", AF_INET6));
+ tt_int_op(0,==, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
/* We should have 4 countries: ??, ab, xy, zz. */
- test_eq(4, geoip_get_n_countries());
+ tt_int_op(4,==, geoip_get_n_countries());
memset(&in6, 0, sizeof(in6));
CHECK_COUNTRY("??", 3);
@@ -844,9 +858,9 @@ test_geoip(void)
CHECK_COUNTRY("xy", 190);
CHECK_COUNTRY("??", 2000);
- test_eq(0, geoip_get_country_by_ipv4(3));
+ tt_int_op(0,==, geoip_get_country_by_ipv4(3));
SET_TEST_IPV6(3);
- test_eq(0, geoip_get_country_by_ipv6(&in6));
+ tt_int_op(0,==, geoip_get_country_by_ipv6(&in6));
get_options_mutable()->BridgeRelay = 1;
get_options_mutable()->BridgeRecordUsageByCountry = 1;
@@ -869,41 +883,41 @@ test_geoip(void)
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
}
geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
- test_assert(s);
- test_assert(v);
- test_streq("zz=24,ab=16,xy=8", s);
- test_streq("v4=16,v6=16", v);
+ tt_assert(s);
+ tt_assert(v);
+ tt_str_op("zz=24,ab=16,xy=8",==, s);
+ tt_str_op("v4=16,v6=16",==, v);
tor_free(s);
tor_free(v);
/* Now clear out all the AB observations. */
geoip_remove_old_clients(now-6000);
geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
- test_assert(s);
- test_assert(v);
- test_streq("zz=24,xy=8", s);
- test_streq("v4=16,v6=16", v);
+ tt_assert(s);
+ tt_assert(v);
+ tt_str_op("zz=24,xy=8",==, s);
+ tt_str_op("v4=16,v6=16",==, v);
tor_free(s);
tor_free(v);
/* Start testing bridge statistics by making sure that we don't output
* bridge stats without initializing them. */
s = geoip_format_bridge_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Initialize stats and generate the bridge-stats history string out of
* the connecting clients added above. */
geoip_bridge_stats_init(now);
s = geoip_format_bridge_stats(now + 86400);
- test_assert(s);
- test_streq(bridge_stats_1, s);
+ tt_assert(s);
+ tt_str_op(bridge_stats_1,==, s);
tor_free(s);
/* Stop collecting bridge stats and make sure we don't write a history
* string anymore. */
geoip_bridge_stats_term();
s = geoip_format_bridge_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Stop being a bridge and start being a directory mirror that gathers
* directory request statistics. */
@@ -917,7 +931,7 @@ test_geoip(void)
SET_TEST_ADDRESS(100);
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
s = geoip_format_dirreq_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Initialize stats, note one connecting client, and generate the
* dirreq-stats history string. */
@@ -925,7 +939,7 @@ test_geoip(void)
SET_TEST_ADDRESS(100);
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
s = geoip_format_dirreq_stats(now + 86400);
- test_streq(dirreq_stats_1, s);
+ tt_str_op(dirreq_stats_1,==, s);
tor_free(s);
/* Stop collecting stats, add another connecting client, and ensure we
@@ -934,7 +948,7 @@ test_geoip(void)
SET_TEST_ADDRESS(101);
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
s = geoip_format_dirreq_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Re-start stats, add a connecting client, reset stats, and make sure
* that we get an all empty history string. */
@@ -943,20 +957,20 @@ test_geoip(void)
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
geoip_reset_dirreq_stats(now);
s = geoip_format_dirreq_stats(now + 86400);
- test_streq(dirreq_stats_2, s);
+ tt_str_op(dirreq_stats_2,==, s);
tor_free(s);
/* Note a successful network status response and make sure that it
* appears in the history string. */
geoip_note_ns_response(GEOIP_SUCCESS);
s = geoip_format_dirreq_stats(now + 86400);
- test_streq(dirreq_stats_3, s);
+ tt_str_op(dirreq_stats_3,==, s);
tor_free(s);
/* Start a tunneled directory request. */
geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
s = geoip_format_dirreq_stats(now + 86400);
- test_streq(dirreq_stats_4, s);
+ tt_str_op(dirreq_stats_4,==, s);
tor_free(s);
/* Stop collecting directory request statistics and start gathering
@@ -970,7 +984,7 @@ test_geoip(void)
SET_TEST_ADDRESS(100);
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
s = geoip_format_entry_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Initialize stats, note one connecting client, and generate the
* entry-stats history string. */
@@ -978,7 +992,7 @@ test_geoip(void)
SET_TEST_ADDRESS(100);
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
s = geoip_format_entry_stats(now + 86400);
- test_streq(entry_stats_1, s);
+ tt_str_op(entry_stats_1,==, s);
tor_free(s);
/* Stop collecting stats, add another connecting client, and ensure we
@@ -987,7 +1001,7 @@ test_geoip(void)
SET_TEST_ADDRESS(101);
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
s = geoip_format_entry_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Re-start stats, add a connecting client, reset stats, and make sure
* that we get an all empty history string. */
@@ -996,7 +1010,7 @@ test_geoip(void)
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
geoip_reset_entry_stats(now);
s = geoip_format_entry_stats(now + 86400);
- test_streq(entry_stats_2, s);
+ tt_str_op(entry_stats_2,==, s);
tor_free(s);
/* Stop collecting entry statistics. */
@@ -1009,7 +1023,7 @@ test_geoip(void)
}
static void
-test_geoip_with_pt(void)
+test_geoip_with_pt(void *arg)
{
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
char *s = NULL;
@@ -1017,6 +1031,7 @@ test_geoip_with_pt(void)
tor_addr_t addr;
struct in6_addr in6;
+ (void)arg;
get_options_mutable()->BridgeRelay = 1;
get_options_mutable()->BridgeRecordUsageByCountry = 1;
@@ -1068,7 +1083,7 @@ test_geoip_with_pt(void)
/* Test the transport history string. */
s = geoip_get_transport_history();
tor_assert(s);
- test_streq(s, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
+ tt_str_op(s,==, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
"entropy=8,fire=8,google=8");
/* Stop collecting entry statistics. */
@@ -1085,7 +1100,7 @@ test_geoip_with_pt(void)
/** Run unit tests for stats code. */
static void
-test_stats(void)
+test_stats(void *arg)
{
time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
char *s = NULL;
@@ -1093,10 +1108,11 @@ test_stats(void)
/* Start with testing exit port statistics; we shouldn't collect exit
* stats without initializing them. */
+ (void)arg;
rep_hist_note_exit_stream_opened(80);
rep_hist_note_exit_bytes(80, 100, 10000);
s = rep_hist_format_exit_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Initialize stats, note some streams and bytes, and generate history
* string. */
@@ -1107,10 +1123,10 @@ test_stats(void)
rep_hist_note_exit_bytes(443, 100, 10000);
rep_hist_note_exit_bytes(443, 100, 10000);
s = rep_hist_format_exit_stats(now + 86400);
- test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"exit-kibibytes-written 80=1,443=1,other=0\n"
"exit-kibibytes-read 80=10,443=20,other=0\n"
- "exit-streams-opened 80=4,443=4,other=0\n", s);
+ "exit-streams-opened 80=4,443=4,other=0\n",==, s);
tor_free(s);
/* Add a few bytes on 10 more ports and ensure that only the top 10
@@ -1120,13 +1136,13 @@ test_stats(void)
rep_hist_note_exit_stream_opened(i);
}
s = rep_hist_format_exit_stats(now + 86400);
- test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"exit-kibibytes-written 52=1,53=1,54=1,55=1,56=1,57=1,58=1,"
"59=1,80=1,443=1,other=1\n"
"exit-kibibytes-read 52=1,53=1,54=1,55=1,56=1,57=1,58=1,"
"59=1,80=10,443=20,other=1\n"
"exit-streams-opened 52=4,53=4,54=4,55=4,56=4,57=4,58=4,"
- "59=4,80=4,443=4,other=4\n", s);
+ "59=4,80=4,443=4,other=4\n",==, s);
tor_free(s);
/* Stop collecting stats, add some bytes, and ensure we don't generate
@@ -1134,7 +1150,7 @@ test_stats(void)
rep_hist_exit_stats_term();
rep_hist_note_exit_bytes(80, 100, 10000);
s = rep_hist_format_exit_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Re-start stats, add some bytes, reset stats, and see what history we
* get when observing no streams or bytes at all. */
@@ -1143,17 +1159,17 @@ test_stats(void)
rep_hist_note_exit_bytes(80, 100, 10000);
rep_hist_reset_exit_stats(now);
s = rep_hist_format_exit_stats(now + 86400);
- test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"exit-kibibytes-written other=0\n"
"exit-kibibytes-read other=0\n"
- "exit-streams-opened other=0\n", s);
+ "exit-streams-opened other=0\n",==, s);
tor_free(s);
/* Continue with testing connection statistics; we shouldn't collect
* conn stats without initializing them. */
rep_hist_note_or_conn_bytes(1, 20, 400, now);
s = rep_hist_format_conn_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Initialize stats, note bytes, and generate history string. */
rep_hist_conn_stats_init(now);
@@ -1162,7 +1178,7 @@ test_stats(void)
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 10);
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15);
s = rep_hist_format_conn_stats(now + 86400);
- test_streq("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n", s);
+ tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n",==, s);
tor_free(s);
/* Stop collecting stats, add some bytes, and ensure we don't generate
@@ -1170,7 +1186,7 @@ test_stats(void)
rep_hist_conn_stats_term();
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15);
s = rep_hist_format_conn_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Re-start stats, add some bytes, reset stats, and see what history we
* get when observing no bytes at all. */
@@ -1181,26 +1197,26 @@ test_stats(void)
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15);
rep_hist_reset_conn_stats(now);
s = rep_hist_format_conn_stats(now + 86400);
- test_streq("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n", s);
+ tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n",==, s);
tor_free(s);
/* Continue with testing buffer statistics; we shouldn't collect buffer
* stats without initializing them. */
rep_hist_add_buffer_stats(2.0, 2.0, 20);
s = rep_hist_format_buffer_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Initialize stats, add statistics for a single circuit, and generate
* the history string. */
rep_hist_buffer_stats_init(now);
rep_hist_add_buffer_stats(2.0, 2.0, 20);
s = rep_hist_format_buffer_stats(now + 86400);
- test_streq("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ tt_str_op("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"cell-processed-cells 20,0,0,0,0,0,0,0,0,0\n"
"cell-queued-cells 2.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,"
"0.00,0.00\n"
"cell-time-in-queue 2,0,0,0,0,0,0,0,0,0\n"
- "cell-circuits-per-decile 1\n", s);
+ "cell-circuits-per-decile 1\n",==, s);
tor_free(s);
/* Add nineteen more circuit statistics to the one that's already in the
@@ -1210,12 +1226,12 @@ test_stats(void)
for (i = 20; i < 30; i++)
rep_hist_add_buffer_stats(3.5, 3.5, i);
s = rep_hist_format_buffer_stats(now + 86400);
- test_streq("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ tt_str_op("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"cell-processed-cells 29,28,27,26,25,24,23,22,21,20\n"
"cell-queued-cells 2.75,2.75,2.75,2.75,2.75,2.75,2.75,2.75,"
"2.75,2.75\n"
"cell-time-in-queue 3,3,3,3,3,3,3,3,3,3\n"
- "cell-circuits-per-decile 2\n", s);
+ "cell-circuits-per-decile 2\n",==, s);
tor_free(s);
/* Stop collecting stats, add statistics for one circuit, and ensure we
@@ -1223,7 +1239,7 @@ test_stats(void)
rep_hist_buffer_stats_term();
rep_hist_add_buffer_stats(2.0, 2.0, 20);
s = rep_hist_format_buffer_stats(now + 86400);
- test_assert(!s);
+ tt_assert(!s);
/* Re-start stats, add statistics for one circuit, reset stats, and make
* sure that the history has all zeros. */
@@ -1231,46 +1247,21 @@ test_stats(void)
rep_hist_add_buffer_stats(2.0, 2.0, 20);
rep_hist_reset_buffer_stats(now);
s = rep_hist_format_buffer_stats(now + 86400);
- test_streq("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ tt_str_op("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"cell-processed-cells 0,0,0,0,0,0,0,0,0,0\n"
"cell-queued-cells 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,"
"0.00,0.00\n"
"cell-time-in-queue 0,0,0,0,0,0,0,0,0,0\n"
- "cell-circuits-per-decile 0\n", s);
+ "cell-circuits-per-decile 0\n",==, s);
done:
tor_free(s);
}
-static void *
-legacy_test_setup(const struct testcase_t *testcase)
-{
- return testcase->setup_data;
-}
-
-void
-legacy_test_helper(void *data)
-{
- void (*fn)(void) = data;
- fn();
-}
-
-static int
-legacy_test_cleanup(const struct testcase_t *testcase, void *ptr)
-{
- (void)ptr;
- (void)testcase;
- return 1;
-}
-
-const struct testcase_setup_t legacy_setup = {
- legacy_test_setup, legacy_test_cleanup
-};
-
#define ENT(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_ ## name }
+ { #name, test_ ## name , 0, NULL, NULL }
#define FORK(name) \
- { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_ ## name }
+ { #name, test_ ## name , TT_FORK, NULL, NULL }
static struct testcase_t test_array[] = {
ENT(onion_handshake),
@@ -1306,6 +1297,7 @@ extern struct testcase_t circuitmux_tests[];
extern struct testcase_t cell_queue_tests[];
extern struct testcase_t options_tests[];
extern struct testcase_t socks_tests[];
+extern struct testcase_t entrynodes_tests[];
extern struct testcase_t extorport_tests[];
extern struct testcase_t controller_event_tests[];
extern struct testcase_t logging_tests[];
@@ -1313,8 +1305,10 @@ extern struct testcase_t hs_tests[];
extern struct testcase_t nodelist_tests[];
extern struct testcase_t routerkeys_tests[];
extern struct testcase_t oom_tests[];
+extern struct testcase_t accounting_tests[];
extern struct testcase_t policy_tests[];
extern struct testcase_t status_tests[];
+extern struct testcase_t routerset_tests[];
static struct testgroup_t testgroups[] = {
{ "", test_array },
@@ -1337,14 +1331,17 @@ static struct testgroup_t testgroups[] = {
{ "circuitlist/", circuitlist_tests },
{ "circuitmux/", circuitmux_tests },
{ "options/", options_tests },
+ { "entrynodes/", entrynodes_tests },
{ "extorport/", extorport_tests },
{ "control/", controller_event_tests },
{ "hs/", hs_tests },
{ "nodelist/", nodelist_tests },
{ "routerkeys/", routerkeys_tests },
{ "oom/", oom_tests },
+ { "accounting/", accounting_tests },
{ "policy/" , policy_tests },
{ "status/" , status_tests },
+ { "routerset/" , routerset_tests },
END_OF_GROUPS
};
@@ -1370,6 +1367,7 @@ main(int c, const char **v)
options = options_new();
tor_threads_init();
init_logging();
+ configure_backtrace_handler(get_version());
for (i_out = i = 1; i < c; ++i) {
if (!strcmp(v[i], "--warn")) {
diff --git a/src/test/test.h b/src/test/test.h
index b9e4d5bdb4..8eb2dfc016 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -22,25 +22,6 @@
#define PRETTY_FUNCTION ""
#endif
-#define test_fail_msg(msg) TT_DIE((msg))
-
-#define test_fail() test_fail_msg("Assertion failed.")
-
-#define test_assert(expr) tt_assert(expr)
-
-#define test_eq(expr1, expr2) tt_int_op((expr1), ==, (expr2))
-#define test_eq_ptr(expr1, expr2) tt_ptr_op((expr1), ==, (expr2))
-#define test_neq(expr1, expr2) tt_int_op((expr1), !=, (expr2))
-#define test_neq_ptr(expr1, expr2) tt_ptr_op((expr1), !=, (expr2))
-#define test_streq(expr1, expr2) tt_str_op((expr1), ==, (expr2))
-#define test_strneq(expr1, expr2) tt_str_op((expr1), !=, (expr2))
-
-#define test_mem_op(expr1, op, expr2, len) \
- tt_mem_op((expr1), op, (expr2), (len))
-
-#define test_memeq(expr1, expr2, len) test_mem_op((expr1), ==, (expr2), len)
-#define test_memneq(expr1, expr2, len) test_mem_op((expr1), !=, (expr2), len)
-
/* As test_mem_op, but decodes 'hex' before comparing. There must be a
* local char* variable called mem_op_hex_tmp for this to work. */
#define test_mem_op_hex(expr1, op, hex) \
@@ -50,7 +31,7 @@
mem_op_hex_tmp = tor_malloc(length/2); \
tor_assert((length&1)==0); \
base16_decode(mem_op_hex_tmp, length/2, hex, length); \
- test_mem_op(expr1, op, mem_op_hex_tmp, length/2); \
+ tt_mem_op(expr1, op, mem_op_hex_tmp, length/2); \
STMT_END
#define test_memeq_hex(expr1, hex) test_mem_op_hex(expr1, ==, hex)
@@ -85,9 +66,6 @@
const char *get_fname(const char *name);
crypto_pk_t *pk_generate(int idx);
-void legacy_test_helper(void *data);
-extern const struct testcase_setup_t legacy_setup;
-
#define US2_CONCAT_2__(a, b) a ## __ ## b
#define US_CONCAT_2__(a, b) a ## _ ## b
#define US_CONCAT_3__(a, b, c) a ## _ ## b ## _ ## c
diff --git a/src/test/test_accounting.c b/src/test/test_accounting.c
new file mode 100644
index 0000000000..25908e942c
--- /dev/null
+++ b/src/test/test_accounting.c
@@ -0,0 +1,76 @@
+#include "or.h"
+#include "test.h"
+#define HIBERNATE_PRIVATE
+#include "hibernate.h"
+#include "config.h"
+#define STATEFILE_PRIVATE
+#include "statefile.h"
+
+#define NS_MODULE accounting
+
+#define NS_SUBMODULE limits
+
+/*
+ * Test to make sure accounting triggers hibernation
+ * correctly with both sum or max rules set
+ */
+
+static or_state_t *or_state;
+NS_DECL(or_state_t *, get_or_state, (void));
+static or_state_t *
+NS(get_or_state)(void)
+{
+ return or_state;
+}
+
+static void
+test_accounting_limits(void *arg)
+{
+ or_options_t *options = get_options_mutable();
+ time_t fake_time = time(NULL);
+ (void) arg;
+
+ NS_MOCK(get_or_state);
+ or_state = or_state_new();
+
+ options->AccountingMax = 100;
+ options->AccountingRule = ACCT_MAX;
+
+ tor_assert(accounting_is_enabled(options));
+ configure_accounting(fake_time);
+
+ accounting_add_bytes(10, 0, 1);
+ fake_time += 1;
+ consider_hibernation(fake_time);
+ tor_assert(we_are_hibernating() == 0);
+
+ accounting_add_bytes(90, 0, 1);
+ fake_time += 1;
+ consider_hibernation(fake_time);
+ tor_assert(we_are_hibernating() == 1);
+
+ options->AccountingMax = 200;
+ options->AccountingRule = ACCT_SUM;
+
+ accounting_add_bytes(0, 10, 1);
+ fake_time += 1;
+ consider_hibernation(fake_time);
+ tor_assert(we_are_hibernating() == 0);
+
+ accounting_add_bytes(0, 90, 1);
+ fake_time += 1;
+ consider_hibernation(fake_time);
+ tor_assert(we_are_hibernating() == 1);
+ goto done;
+ done:
+ NS_UNMOCK(get_or_state);
+ or_state_free(or_state);
+}
+
+#undef NS_SUBMODULE
+
+struct testcase_t accounting_tests[] = {
+ { "bwlimits", test_accounting_limits, TT_FORK, NULL, NULL },
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index 50011e606b..043c2a0d4a 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -10,49 +10,50 @@
#include "addressmap.h"
static void
-test_addr_basic(void)
+test_addr_basic(void *arg)
{
uint32_t u32;
uint16_t u16;
char *cp;
/* Test addr_port_lookup */
+ (void)arg;
cp = NULL; u32 = 3; u16 = 3;
- test_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
- test_streq(cp, "1.2.3.4");
- test_eq(u32, 0x01020304u);
- test_eq(u16, 0);
+ tt_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
+ tt_str_op(cp,==, "1.2.3.4");
+ tt_int_op(u32,==, 0x01020304u);
+ tt_int_op(u16,==, 0);
tor_free(cp);
- test_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
- test_streq(cp, "4.3.2.1");
- test_eq(u32, 0x04030201u);
- test_eq(u16, 99);
+ tt_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
+ tt_str_op(cp,==, "4.3.2.1");
+ tt_int_op(u32,==, 0x04030201u);
+ tt_int_op(u16,==, 99);
tor_free(cp);
- test_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040",
+ tt_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040",
&cp, NULL, &u16));
- test_streq(cp, "nonexistent.address");
- test_eq(u16, 4040);
+ tt_str_op(cp,==, "nonexistent.address");
+ tt_int_op(u16,==, 4040);
tor_free(cp);
- test_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
- test_streq(cp, "localhost");
- test_eq(u32, 0x7f000001u);
- test_eq(u16, 9999);
+ tt_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
+ tt_str_op(cp,==, "localhost");
+ tt_int_op(u32,==, 0x7f000001u);
+ tt_int_op(u16,==, 9999);
tor_free(cp);
u32 = 3;
- test_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16));
- test_eq_ptr(cp, NULL);
- test_eq(u32, 0x7f000001u);
- test_eq(u16, 0);
+ tt_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16));
+ tt_ptr_op(cp,==, NULL);
+ tt_int_op(u32,==, 0x7f000001u);
+ tt_int_op(u16,==, 0);
tor_free(cp);
- test_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL));
+ tt_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL));
tor_free(cp);
- test_eq(0, addr_mask_get_bits(0x0u));
- test_eq(32, addr_mask_get_bits(0xFFFFFFFFu));
- test_eq(16, addr_mask_get_bits(0xFFFF0000u));
- test_eq(31, addr_mask_get_bits(0xFFFFFFFEu));
- test_eq(1, addr_mask_get_bits(0x80000000u));
+ tt_int_op(0,==, addr_mask_get_bits(0x0u));
+ tt_int_op(32,==, addr_mask_get_bits(0xFFFFFFFFu));
+ tt_int_op(16,==, addr_mask_get_bits(0xFFFF0000u));
+ tt_int_op(31,==, addr_mask_get_bits(0xFFFFFFFEu));
+ tt_int_op(1,==, addr_mask_get_bits(0x80000000u));
/* Test inet_ntop */
{
@@ -61,15 +62,15 @@ test_addr_basic(void)
struct in_addr in;
/* good round trip */
- test_eq(tor_inet_pton(AF_INET, ip, &in), 1);
- test_eq_ptr(tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf)), &tmpbuf);
- test_streq(tmpbuf, ip);
+ tt_int_op(tor_inet_pton(AF_INET, ip, &in),==, 1);
+ tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf)),==, &tmpbuf);
+ tt_str_op(tmpbuf,==, ip);
/* just enough buffer length */
- test_streq(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip) + 1), ip);
+ tt_str_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip) + 1),==, ip);
/* too short buffer */
- test_eq_ptr(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip)), NULL);
+ tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip)),==, NULL);
}
done:
@@ -96,67 +97,68 @@ test_addr_basic(void)
/** Helper: Assert that two strings both decode as IPv6 addresses with
* tor_inet_pton(), and both decode to the same address. */
-#define test_pton6_same(a,b) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \
- test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \
- test_op_ip6_(&a1,==,&a2,#a,#b); \
+#define test_pton6_same(a,b) STMT_BEGIN \
+ tt_int_op(tor_inet_pton(AF_INET6, a, &a1), ==, 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, b, &a2), ==, 1); \
+ test_op_ip6_(&a1,==,&a2,#a,#b); \
STMT_END
/** Helper: Assert that <b>a</b> is recognized as a bad IPv6 address by
* tor_inet_pton(). */
#define test_pton6_bad(a) \
- test_eq(0, tor_inet_pton(AF_INET6, a, &a1))
+ tt_int_op(0, ==, tor_inet_pton(AF_INET6, a, &a1))
/** Helper: assert that <b>a</b>, when parsed by tor_inet_pton() and displayed
* with tor_inet_ntop(), yields <b>b</b>. Also assert that <b>b</b> parses to
* the same value as <b>a</b>. */
-#define test_ntop6_reduces(a,b) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \
- test_streq(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), b); \
- test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \
- test_op_ip6_(&a1, ==, &a2, a, b); \
+#define test_ntop6_reduces(a,b) STMT_BEGIN \
+ tt_int_op(tor_inet_pton(AF_INET6, a, &a1), ==, 1); \
+ tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), ==, b); \
+ tt_int_op(tor_inet_pton(AF_INET6, b, &a2), ==, 1); \
+ test_op_ip6_(&a1, ==, &a2, a, b); \
STMT_END
/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
* passes tor_addr_is_internal() with <b>for_listening</b>. */
#define test_internal_ip(a,for_listening) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
t1.family = AF_INET6; \
if (!tor_addr_is_internal(&t1, for_listening)) \
- test_fail_msg( a "was not internal."); \
+ TT_DIE(("%s was not internal", a)); \
STMT_END
/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
* does not pass tor_addr_is_internal() with <b>for_listening</b>. */
#define test_external_ip(a,for_listening) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
t1.family = AF_INET6; \
if (tor_addr_is_internal(&t1, for_listening)) \
- test_fail_msg(a "was not external."); \
+ TT_DIE(("%s was not internal", a)); \
STMT_END
/** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
* tor_inet_pton(), give addresses that compare in the order defined by
* <b>op</b> with tor_addr_compare(). */
#define test_addr_compare(a, op, b) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
- test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), ==, 1); \
t1.family = t2.family = AF_INET6; \
r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC); \
if (!(r op 0)) \
- test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0"); \
+ TT_DIE(("Failed: tor_addr_compare(%s,%s) %s 0", a, b, #op));\
STMT_END
/** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by
* tor_inet_pton(), give addresses that compare in the order defined by
* <b>op</b> with tor_addr_compare_masked() with <b>m</b> masked. */
#define test_addr_compare_masked(a, op, b, m) STMT_BEGIN \
- test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \
- test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
+ tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), ==, 1); \
t1.family = t2.family = AF_INET6; \
r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC); \
if (!(r op 0)) \
- test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0"); \
+ TT_DIE(("Failed: tor_addr_compare_masked(%s,%s,%d) %s 0", \
+ a, b, m, #op)); \
STMT_END
/** Helper: assert that <b>xx</b> is parseable as a masked IPv6 address with
@@ -165,21 +167,21 @@ test_addr_basic(void)
* as <b>pt1..pt2</b>. */
#define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2) \
STMT_BEGIN \
- test_eq(tor_addr_parse_mask_ports(xx, 0, &t1, &mask, &port1, &port2), \
- f); \
+ tt_int_op(tor_addr_parse_mask_ports(xx, 0, &t1, &mask, &port1, &port2), \
+ ==, f); \
p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug)); \
- test_eq(htonl(ip1), tor_addr_to_in6_addr32(&t1)[0]); \
- test_eq(htonl(ip2), tor_addr_to_in6_addr32(&t1)[1]); \
- test_eq(htonl(ip3), tor_addr_to_in6_addr32(&t1)[2]); \
- test_eq(htonl(ip4), tor_addr_to_in6_addr32(&t1)[3]); \
- test_eq(mask, mm); \
- test_eq(port1, pt1); \
- test_eq(port2, pt2); \
+ tt_int_op(htonl(ip1), ==, tor_addr_to_in6_addr32(&t1)[0]); \
+ tt_int_op(htonl(ip2), ==, tor_addr_to_in6_addr32(&t1)[1]); \
+ tt_int_op(htonl(ip3), ==, tor_addr_to_in6_addr32(&t1)[2]); \
+ tt_int_op(htonl(ip4), ==, tor_addr_to_in6_addr32(&t1)[3]); \
+ tt_int_op(mask, ==, mm); \
+ tt_uint_op(port1, ==, pt1); \
+ tt_uint_op(port2, ==, pt2); \
STMT_END
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */
static void
-test_addr_ip6_helpers(void)
+test_addr_ip6_helpers(void *arg)
{
char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN];
char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN];
@@ -194,28 +196,29 @@ test_addr_ip6_helpers(void)
struct sockaddr_in6 *sin6;
/* Test tor_inet_ntop and tor_inet_pton: IPv6 */
+ (void)arg;
{
const char *ip = "2001::1234";
const char *ip_ffff = "::ffff:192.168.1.2";
/* good round trip */
- test_eq(tor_inet_pton(AF_INET6, ip, &a1), 1);
- test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), &buf);
- test_streq(buf, ip);
+ tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),==, 1);
+ tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),==, &buf);
+ tt_str_op(buf,==, ip);
/* good round trip - ::ffff:0:0 style */
- test_eq(tor_inet_pton(AF_INET6, ip_ffff, &a2), 1);
- test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)), &buf);
- test_streq(buf, ip_ffff);
+ tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),==, 1);
+ tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),==, &buf);
+ tt_str_op(buf,==, ip_ffff);
/* just long enough buffer (remember \0) */
- test_streq(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1), ip);
- test_streq(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),
+ tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),==, ip);
+ tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),==,
ip_ffff);
/* too short buffer (remember \0) */
- test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)), NULL);
- test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)), NULL);
+ tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),==, NULL);
+ tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),==, NULL);
}
/* ==== Converting to and from sockaddr_t. */
@@ -224,16 +227,16 @@ test_addr_ip6_helpers(void)
sin->sin_port = htons(9090);
sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/
tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, &port1);
- test_eq(tor_addr_family(&t1), AF_INET);
- test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102);
+ tt_int_op(tor_addr_family(&t1),==, AF_INET);
+ tt_int_op(tor_addr_to_ipv4h(&t1),==, 0x7f7f0102);
tt_int_op(port1, ==, 9090);
memset(&sa_storage, 0, sizeof(sa_storage));
- test_eq(sizeof(struct sockaddr_in),
+ tt_int_op(sizeof(struct sockaddr_in),==,
tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage,
sizeof(sa_storage)));
- test_eq(1234, ntohs(sin->sin_port));
- test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr));
+ tt_int_op(1234,==, ntohs(sin->sin_port));
+ tt_int_op(0x7f7f0102,==, ntohl(sin->sin_addr.s_addr));
memset(&sa_storage, 0, sizeof(sa_storage));
sin6 = (struct sockaddr_in6 *)&sa_storage;
@@ -241,37 +244,37 @@ test_addr_ip6_helpers(void)
sin6->sin6_port = htons(7070);
sin6->sin6_addr.s6_addr[0] = 128;
tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, &port1);
- test_eq(tor_addr_family(&t1), AF_INET6);
+ tt_int_op(tor_addr_family(&t1),==, AF_INET6);
tt_int_op(port1, ==, 7070);
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
- test_streq(p1, "8000::");
+ tt_str_op(p1,==, "8000::");
memset(&sa_storage, 0, sizeof(sa_storage));
- test_eq(sizeof(struct sockaddr_in6),
+ tt_int_op(sizeof(struct sockaddr_in6),==,
tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage,
sizeof(sa_storage)));
- test_eq(AF_INET6, sin6->sin6_family);
- test_eq(9999, ntohs(sin6->sin6_port));
- test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
+ tt_int_op(AF_INET6,==, sin6->sin6_family);
+ tt_int_op(9999,==, ntohs(sin6->sin6_port));
+ tt_int_op(0x80000000,==, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
/* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we
* have a good resolver. */
- test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
- test_eq(AF_INET, tor_addr_family(&t1));
- test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182);
+ tt_int_op(0,==, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
+ tt_int_op(AF_INET,==, tor_addr_family(&t1));
+ tt_int_op(tor_addr_to_ipv4h(&t1),==, 0x7f808182);
- test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
- test_eq(AF_INET6, tor_addr_family(&t1));
- test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]);
- test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
- test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]);
+ tt_int_op(0,==, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
+ tt_int_op(AF_INET6,==, tor_addr_family(&t1));
+ tt_int_op(0x90,==, tor_addr_to_in6_addr8(&t1)[0]);
+ tt_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
+ tt_int_op(0x05,==, tor_addr_to_in6_addr8(&t1)[15]);
/* === Test pton: valid af_inet6 */
/* Simple, valid parsing. */
r = tor_inet_pton(AF_INET6,
"0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1);
- test_assert(r==1);
- for (i=0;i<16;++i) { test_eq(i+1, (int)a1.s6_addr[i]); }
+ tt_int_op(r, ==, 1);
+ for (i=0;i<16;++i) { tt_int_op(i+1,==, (int)a1.s6_addr[i]); }
/* ipv4 ending. */
test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10",
"0102:0304:0506:0708:090A:0B0C:13.14.15.16");
@@ -311,7 +314,7 @@ test_addr_ip6_helpers(void)
"1000:1:0:7::");
/* Bad af param */
- test_eq(tor_inet_pton(AF_UNSPEC, 0, 0), -1);
+ tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),==, -1);
/* === Test pton: invalid in6. */
test_pton6_bad("foobar.");
@@ -414,10 +417,10 @@ test_addr_ip6_helpers(void)
test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", 0, &t1, NULL, NULL, NULL);
tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL);
- test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
+ tt_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", 0, &t1, NULL, NULL, NULL);
tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL);
- test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
+ tt_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
/* test compare_masked */
test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
@@ -426,113 +429,113 @@ test_addr_ip6_helpers(void)
test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80);
/* Test undecorated tor_addr_to_str */
- test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
+ tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
- test_streq(p1, "123:45:6789::5005:11");
- test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1"));
+ tt_str_op(p1,==, "123:45:6789::5005:11");
+ tt_int_op(AF_INET,==, tor_addr_parse(&t1, "18.0.0.1"));
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
- test_streq(p1, "18.0.0.1");
+ tt_str_op(p1,==, "18.0.0.1");
/* Test decorated tor_addr_to_str */
- test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
+ tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "[123:45:6789::5005:11]");
- test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1"));
+ tt_str_op(p1,==, "[123:45:6789::5005:11]");
+ tt_int_op(AF_INET,==, tor_addr_parse(&t1, "18.0.0.1"));
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "18.0.0.1");
+ tt_str_op(p1,==, "18.0.0.1");
/* Test buffer bounds checking of tor_addr_to_str */
- test_eq(AF_INET6, tor_addr_parse(&t1, "::")); /* 2 + \0 */
- test_eq_ptr(tor_addr_to_str(buf, &t1, 2, 0), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 3, 0), "::");
- test_eq_ptr(tor_addr_to_str(buf, &t1, 4, 1), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 5, 1), "[::]");
-
- test_eq(AF_INET6, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */
- test_eq_ptr(tor_addr_to_str(buf, &t1, 10, 0), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 11, 0), "2000::1337");
- test_eq_ptr(tor_addr_to_str(buf, &t1, 12, 1), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 13, 1), "[2000::1337]");
-
- test_eq(AF_INET, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */
- test_eq_ptr(tor_addr_to_str(buf, &t1, 7, 0), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 8, 0), "1.2.3.4");
-
- test_eq(AF_INET, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */
- test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 0), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 16, 0), "255.255.255.255");
- test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 1), NULL); /* too short buf */
- test_streq(tor_addr_to_str(buf, &t1, 16, 1), "255.255.255.255");
+ tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "::")); /* 2 + \0 */
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),==, "::");
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),==, "[::]");
+
+ tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),==, "2000::1337");
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),==, "[2000::1337]");
+
+ tt_int_op(AF_INET,==, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),==, "1.2.3.4");
+
+ tt_int_op(AF_INET,==, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),==, "255.255.255.255");
+ tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),==, NULL); /* too short buf */
+ tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),==, "255.255.255.255");
t1.family = AF_UNSPEC;
- test_eq_ptr(tor_addr_to_str(buf, &t1, sizeof(buf), 0), NULL);
+ tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),==, NULL);
/* Test tor_addr_parse_PTR_name */
i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0);
- test_eq(0, i);
+ tt_int_op(0,==, i);
i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1);
- test_eq(0, i);
+ tt_int_op(0,==, i);
i = tor_addr_parse_PTR_name(&t1, "9999999999999999999999999999.in-addr.arpa",
AF_UNSPEC, 1);
- test_eq(-1, i);
+ tt_int_op(-1,==, i);
i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa",
AF_UNSPEC, 1);
- test_eq(1, i);
- test_eq(tor_addr_family(&t1), AF_INET);
+ tt_int_op(1,==, i);
+ tt_int_op(tor_addr_family(&t1),==, AF_INET);
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "192.168.0.1");
+ tt_str_op(p1,==, "192.168.0.1");
i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0);
- test_eq(0, i);
+ tt_int_op(0,==, i);
i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1);
- test_eq(1, i);
+ tt_int_op(1,==, i);
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "192.168.0.99");
+ tt_str_op(p1,==, "192.168.0.99");
memset(&t1, 0, sizeof(t1));
i = tor_addr_parse_PTR_name(&t1,
"0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f."
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
"ip6.ARPA",
AF_UNSPEC, 0);
- test_eq(1, i);
+ tt_int_op(1,==, i);
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
- test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
+ tt_str_op(p1,==, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
/* Failing cases. */
i = tor_addr_parse_PTR_name(&t1,
"6.7.8.9.a.b.c.d.e.f."
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
"ip6.ARPA",
AF_UNSPEC, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1,
"6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0."
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
"ip6.ARPA",
AF_UNSPEC, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1,
"6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9."
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
"ip6.ARPA",
AF_UNSPEC, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa",
AF_UNSPEC, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa",
AF_UNSPEC, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa",
AF_UNSPEC, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa",
AF_INET6, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
i = tor_addr_parse_PTR_name(&t1,
"6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0."
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
"ip6.ARPA",
AF_INET, 0);
- test_eq(i, -1);
+ tt_int_op(i,==, -1);
/* === Test tor_addr_to_PTR_name */
@@ -544,19 +547,19 @@ test_addr_ip6_helpers(void)
tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL);
/* Check IPv4 PTR - too short buffer */
- test_eq(tor_addr_to_PTR_name(rbuf, 1, &t1), -1);
- test_eq(tor_addr_to_PTR_name(rbuf,
+ tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),==, -1);
+ tt_int_op(tor_addr_to_PTR_name(rbuf,
strlen("3.2.1.127.in-addr.arpa") - 1,
- &t1), -1);
+ &t1),==, -1);
/* Check IPv4 PTR - valid addr */
- test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),
+ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==,
strlen("3.2.1.127.in-addr.arpa"));
- test_streq(rbuf, "3.2.1.127.in-addr.arpa");
+ tt_str_op(rbuf,==, "3.2.1.127.in-addr.arpa");
/* Invalid addr family */
t1.family = AF_UNSPEC;
- test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), -1);
+ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==, -1);
/* Stage IPv6 addr */
memset(&sa_storage, 0, sizeof(sa_storage));
@@ -573,114 +576,114 @@ test_addr_ip6_helpers(void)
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa";
/* Check IPv6 PTR - too short buffer */
- test_eq(tor_addr_to_PTR_name(rbuf, 0, &t1), -1);
- test_eq(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1), -1);
+ tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),==, -1);
+ tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),==, -1);
/* Check IPv6 PTR - valid addr */
- test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),
+ tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==,
strlen(addr_PTR));
- test_streq(rbuf, addr_PTR);
+ tt_str_op(rbuf,==, addr_PTR);
}
/* XXXX turn this into a separate function; it's not all IPv6. */
/* test tor_addr_parse_mask_ports */
test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
0, 0, 0, 0x0000000f, 17, 47, 95);
- test_streq(p1, "::f");
+ tt_str_op(p1,==, "::f");
//test_addr_parse("[::fefe:4.1.1.7/120]:999-1000");
//test_addr_parse_check("::fefe:401:107", 120, 999, 1000);
test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6,
0, 0, 0x0000ffff, 0x04010107, 120, 443, 443);
- test_streq(p1, "::ffff:4.1.1.7");
+ tt_str_op(p1,==, "::ffff:4.1.1.7");
test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6,
0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000);
- test_streq(p1, "abcd:2::44a:0");
+ tt_str_op(p1,==, "abcd:2::44a:0");
/* Try some long addresses. */
r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]",
0, &t1, NULL, NULL, NULL);
- test_assert(r == AF_INET6);
+ tt_assert(r == AF_INET6);
r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]",
0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]",
0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports(
"[ffff:1111:1111:1111:1111:1111:1111:ffff:"
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:"
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:"
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]",
0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Try some failing cases. */
r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0",
0,&t1, NULL, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* This one will get rejected because it isn't a pure prefix. */
r=tor_addr_parse_mask_ports("1.1.2.3/255.255.64.0",0,&t1, &mask,NULL,NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Test for V4-mapped address with mask < 96. (arguably not valid) */
r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/
r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
#if 0
/* Try a mask with a wildcard. */
r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_assert(r == -1);
r=tor_addr_parse_mask_ports("*4/16",TAPMP_EXTENDED_STAR,
&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_assert(r == -1);
r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR,
&t1, &mask, NULL, NULL);
- test_assert(r == -1);
+ tt_assert(r == -1);
#endif
/* Basic mask tests*/
r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL);
- test_assert(r == AF_INET);
+ tt_assert(r == AF_INET);
tt_int_op(mask,==,31);
tt_int_op(tor_addr_family(&t1),==,AF_INET);
tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010202);
r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2);
- test_assert(r == AF_INET);
+ tt_assert(r == AF_INET);
tt_int_op(mask,==,32);
tt_int_op(tor_addr_family(&t1),==,AF_INET);
tt_int_op(tor_addr_to_ipv4h(&t1),==,0x03041020);
- test_assert(port1 == 1);
- test_assert(port2 == 2);
+ tt_assert(port1 == 1);
+ tt_assert(port2 == 2);
r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL);
- test_assert(r == AF_INET);
+ tt_assert(r == AF_INET);
tt_int_op(mask,==,17);
tt_int_op(tor_addr_family(&t1),==,AF_INET);
tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010203);
r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2);
- test_assert(r == AF_INET6);
- test_assert(port1 == 1);
- test_assert(port2 == 65535);
+ tt_assert(r == AF_INET6);
+ tt_assert(port1 == 1);
+ tt_assert(port2 == 65535);
/* Try regular wildcard behavior without TAPMP_EXTENDED_STAR */
r=tor_addr_parse_mask_ports("*:80-443",0,&t1,&mask,&port1,&port2);
tt_int_op(r,==,AF_INET); /* Old users of this always get inet */
@@ -715,11 +718,11 @@ test_addr_ip6_helpers(void)
tt_int_op(port2,==,65535);
/* make sure inet address lengths >= max */
- test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255"));
- test_assert(TOR_ADDR_BUF_LEN >=
+ tt_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255"));
+ tt_assert(TOR_ADDR_BUF_LEN >=
sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"));
- test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr));
+ tt_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr));
/* get interface addresses */
r = get_interface_address6(LOG_DEBUG, AF_INET, &t1);
@@ -736,7 +739,7 @@ test_addr_ip6_helpers(void)
/** Test tor_addr_port_parse(). */
static void
-test_addr_parse(void)
+test_addr_parse(void *arg)
{
int r;
tor_addr_t addr;
@@ -744,89 +747,90 @@ test_addr_parse(void)
uint16_t port = 0;
/* Correct call. */
+ (void)arg;
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.1:1234",
&addr, &port, -1);
- test_assert(r == 0);
+ tt_int_op(r, ==, 0);
tor_addr_to_str(buf, &addr, sizeof(buf), 0);
- test_streq(buf, "192.0.2.1");
- test_eq(port, 1234);
+ tt_str_op(buf,==, "192.0.2.1");
+ tt_int_op(port,==, 1234);
r= tor_addr_port_parse(LOG_DEBUG,
"[::1]:1234",
&addr, &port, -1);
- test_assert(r == 0);
+ tt_int_op(r, ==, 0);
tor_addr_to_str(buf, &addr, sizeof(buf), 0);
- test_streq(buf, "::1");
- test_eq(port, 1234);
+ tt_str_op(buf,==, "::1");
+ tt_int_op(port,==, 1234);
/* Domain name. */
r= tor_addr_port_parse(LOG_DEBUG,
"torproject.org:1234",
&addr, &port, -1);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Only IP. */
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.2",
&addr, &port, -1);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.2",
&addr, &port, 200);
- test_assert(r == 0);
+ tt_int_op(r, ==, 0);
tt_int_op(port,==,200);
r= tor_addr_port_parse(LOG_DEBUG,
"[::1]",
&addr, &port, -1);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r= tor_addr_port_parse(LOG_DEBUG,
"[::1]",
&addr, &port, 400);
- test_assert(r == 0);
+ tt_int_op(r, ==, 0);
tt_int_op(port,==,400);
/* Bad port. */
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.2:66666",
&addr, &port, -1);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.2:66666",
&addr, &port, 200);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Only domain name */
r= tor_addr_port_parse(LOG_DEBUG,
"torproject.org",
&addr, &port, -1);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
r= tor_addr_port_parse(LOG_DEBUG,
"torproject.org",
&addr, &port, 200);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Bad IP address */
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2:1234",
&addr, &port, -1);
- test_assert(r == -1);
+ tt_int_op(r, ==, -1);
/* Make sure that the default port has lower priority than the real
one */
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.2:1337",
&addr, &port, 200);
- test_assert(r == 0);
+ tt_int_op(r, ==, 0);
tt_int_op(port,==,1337);
r= tor_addr_port_parse(LOG_DEBUG,
"[::1]:1369",
&addr, &port, 200);
- test_assert(r == 0);
+ tt_int_op(r, ==, 0);
tt_int_op(port,==,1369);
done:
@@ -1047,7 +1051,7 @@ test_addr_make_null(void *data)
}
#define ADDR_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_addr_ ## name }
+ { #name, test_addr_ ## name , 0, NULL, NULL }
struct testcase_t addr_tests[] = {
ADDR_LEGACY(basic),
diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c
index 45ae82fb85..720ccd4627 100644
--- a/src/test/test_bt_cl.c
+++ b/src/test/test_bt_cl.c
@@ -30,7 +30,12 @@ int
crash(int x)
{
if (crashtype == 0) {
+#if defined(__clang_analyzer__) || defined(__COVERITY__)
+ tor_assert(1 == 0); /* Avert your eyes, clangalyzer and coverity! You
+ * don't need to see us dereference NULL. */
+#else
*(volatile int *)0 = 0;
+#endif
} else if (crashtype == 1) {
tor_assert(1 == 0);
} else if (crashtype == -1) {
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index f24b80f0b0..3ab3d8d8c0 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -27,10 +27,10 @@ test_buffers_basic(void *arg)
* buf_new
****/
if (!(buf = buf_new()))
- test_fail();
+ TT_DIE(("Assertion failed."));
//test_eq(buf_capacity(buf), 4096);
- test_eq(buf_datalen(buf), 0);
+ tt_int_op(buf_datalen(buf),==, 0);
/****
* General pointer frobbing
@@ -40,16 +40,16 @@ test_buffers_basic(void *arg)
}
write_to_buf(str, 256, buf);
write_to_buf(str, 256, buf);
- test_eq(buf_datalen(buf), 512);
+ tt_int_op(buf_datalen(buf),==, 512);
fetch_from_buf(str2, 200, buf);
- test_memeq(str, str2, 200);
- test_eq(buf_datalen(buf), 312);
+ tt_mem_op(str,==, str2, 200);
+ tt_int_op(buf_datalen(buf),==, 312);
memset(str2, 0, sizeof(str2));
fetch_from_buf(str2, 256, buf);
- test_memeq(str+200, str2, 56);
- test_memeq(str, str2+56, 200);
- test_eq(buf_datalen(buf), 56);
+ tt_mem_op(str+200,==, str2, 56);
+ tt_mem_op(str,==, str2+56, 200);
+ tt_int_op(buf_datalen(buf),==, 56);
memset(str2, 0, sizeof(str2));
/* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
* another 3584 bytes, we hit the end. */
@@ -57,16 +57,16 @@ test_buffers_basic(void *arg)
write_to_buf(str, 256, buf);
}
assert_buf_ok(buf);
- test_eq(buf_datalen(buf), 3896);
+ tt_int_op(buf_datalen(buf),==, 3896);
fetch_from_buf(str2, 56, buf);
- test_eq(buf_datalen(buf), 3840);
- test_memeq(str+200, str2, 56);
+ tt_int_op(buf_datalen(buf),==, 3840);
+ tt_mem_op(str+200,==, str2, 56);
for (j=0;j<15;++j) {
memset(str2, 0, sizeof(str2));
fetch_from_buf(str2, 256, buf);
- test_memeq(str, str2, 256);
+ tt_mem_op(str,==, str2, 256);
}
- test_eq(buf_datalen(buf), 0);
+ tt_int_op(buf_datalen(buf),==, 0);
buf_free(buf);
buf = NULL;
@@ -76,7 +76,7 @@ test_buffers_basic(void *arg)
write_to_buf(str+1, 255, buf);
//test_eq(buf_capacity(buf), 256);
fetch_from_buf(str2, 254, buf);
- test_memeq(str+1, str2, 254);
+ tt_mem_op(str+1,==, str2, 254);
//test_eq(buf_capacity(buf), 256);
assert_buf_ok(buf);
write_to_buf(str, 32, buf);
@@ -85,15 +85,15 @@ test_buffers_basic(void *arg)
write_to_buf(str, 256, buf);
assert_buf_ok(buf);
//test_eq(buf_capacity(buf), 512);
- test_eq(buf_datalen(buf), 33+256);
+ tt_int_op(buf_datalen(buf),==, 33+256);
fetch_from_buf(str2, 33, buf);
- test_eq(*str2, str[255]);
+ tt_int_op(*str2,==, str[255]);
- test_memeq(str2+1, str, 32);
+ tt_mem_op(str2+1,==, str, 32);
//test_eq(buf_capacity(buf), 512);
- test_eq(buf_datalen(buf), 256);
+ tt_int_op(buf_datalen(buf),==, 256);
fetch_from_buf(str2, 256, buf);
- test_memeq(str, str2, 256);
+ tt_mem_op(str,==, str2, 256);
/* now try shrinking: case 1. */
buf_free(buf);
@@ -102,10 +102,10 @@ test_buffers_basic(void *arg)
write_to_buf(str,255, buf);
}
//test_eq(buf_capacity(buf), 33668);
- test_eq(buf_datalen(buf), 17085);
+ tt_int_op(buf_datalen(buf),==, 17085);
for (j=0; j < 40; ++j) {
fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
+ tt_mem_op(str2,==, str, 255);
}
/* now try shrinking: case 2. */
@@ -116,7 +116,7 @@ test_buffers_basic(void *arg)
}
for (j=0; j < 20; ++j) {
fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
+ tt_mem_op(str2,==, str, 255);
}
for (j=0;j<80;++j) {
write_to_buf(str,255, buf);
@@ -124,7 +124,7 @@ test_buffers_basic(void *arg)
//test_eq(buf_capacity(buf),33668);
for (j=0; j < 120; ++j) {
fetch_from_buf(str2, 255,buf);
- test_memeq(str2, str, 255);
+ tt_mem_op(str2,==, str, 255);
}
/* Move from buf to buf. */
@@ -133,27 +133,27 @@ test_buffers_basic(void *arg)
buf2 = buf_new_with_capacity(4096);
for (j=0;j<100;++j)
write_to_buf(str, 255, buf);
- test_eq(buf_datalen(buf), 25500);
+ tt_int_op(buf_datalen(buf),==, 25500);
for (j=0;j<100;++j) {
r = 10;
move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 0);
+ tt_int_op(r,==, 0);
}
- test_eq(buf_datalen(buf), 24500);
- test_eq(buf_datalen(buf2), 1000);
+ tt_int_op(buf_datalen(buf),==, 24500);
+ tt_int_op(buf_datalen(buf2),==, 1000);
for (j=0;j<3;++j) {
fetch_from_buf(str2, 255, buf2);
- test_memeq(str2, str, 255);
+ tt_mem_op(str2,==, str, 255);
}
r = 8192; /*big move*/
move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 0);
+ tt_int_op(r,==, 0);
r = 30000; /* incomplete move */
move_buf_to_buf(buf2, buf, &r);
- test_eq(r, 13692);
+ tt_int_op(r,==, 13692);
for (j=0;j<97;++j) {
fetch_from_buf(str2, 255, buf2);
- test_memeq(str2, str, 255);
+ tt_mem_op(str2,==, str, 255);
}
buf_free(buf);
buf_free(buf2);
@@ -163,16 +163,16 @@ test_buffers_basic(void *arg)
cp = "Testing. This is a moderately long Testing string.";
for (j = 0; cp[j]; j++)
write_to_buf(cp+j, 1, buf);
- test_eq(0, buf_find_string_offset(buf, "Testing", 7));
- test_eq(1, buf_find_string_offset(buf, "esting", 6));
- test_eq(1, buf_find_string_offset(buf, "est", 3));
- test_eq(39, buf_find_string_offset(buf, "ing str", 7));
- test_eq(35, buf_find_string_offset(buf, "Testing str", 11));
- test_eq(32, buf_find_string_offset(buf, "ng ", 3));
- test_eq(43, buf_find_string_offset(buf, "string.", 7));
- test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6));
- test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13));
- test_eq(-1, buf_find_string_offset(buf, "ngx", 3));
+ tt_int_op(0,==, buf_find_string_offset(buf, "Testing", 7));
+ tt_int_op(1,==, buf_find_string_offset(buf, "esting", 6));
+ tt_int_op(1,==, buf_find_string_offset(buf, "est", 3));
+ tt_int_op(39,==, buf_find_string_offset(buf, "ing str", 7));
+ tt_int_op(35,==, buf_find_string_offset(buf, "Testing str", 11));
+ tt_int_op(32,==, buf_find_string_offset(buf, "ng ", 3));
+ tt_int_op(43,==, buf_find_string_offset(buf, "string.", 7));
+ tt_int_op(-1,==, buf_find_string_offset(buf, "shrdlu", 6));
+ tt_int_op(-1,==, buf_find_string_offset(buf, "Testing thing", 13));
+ tt_int_op(-1,==, buf_find_string_offset(buf, "ngx", 3));
buf_free(buf);
buf = NULL;
@@ -240,16 +240,16 @@ test_buffer_pullup(void *arg)
/* Make room for 3000 bytes in the first chunk, so that the pullup-move code
* can get tested. */
tt_int_op(fetch_from_buf(tmp, 3000, buf), ==, 3000);
- test_memeq(tmp, stuff, 3000);
+ tt_mem_op(tmp,==, stuff, 3000);
buf_pullup(buf, 2048, 0);
assert_buf_ok(buf);
buf_get_first_chunk_data(buf, &cp, &sz);
tt_ptr_op(cp, !=, NULL);
tt_int_op(sz, >=, 2048);
- test_memeq(cp, stuff+3000, 2048);
+ tt_mem_op(cp,==, stuff+3000, 2048);
tt_int_op(3000, ==, buf_datalen(buf));
tt_int_op(fetch_from_buf(tmp, 3000, buf), ==, 0);
- test_memeq(tmp, stuff+3000, 2048);
+ tt_mem_op(tmp,==, stuff+3000, 2048);
buf_free(buf);
@@ -269,16 +269,16 @@ test_buffer_pullup(void *arg)
buf_get_first_chunk_data(buf, &cp, &sz);
tt_ptr_op(cp, !=, NULL);
tt_int_op(sz, >=, 12500);
- test_memeq(cp, stuff, 12500);
+ tt_mem_op(cp,==, stuff, 12500);
tt_int_op(buf_datalen(buf), ==, 16000);
fetch_from_buf(tmp, 12400, buf);
- test_memeq(tmp, stuff, 12400);
+ tt_mem_op(tmp,==, stuff, 12400);
tt_int_op(buf_datalen(buf), ==, 3600);
fetch_from_buf(tmp, 3500, buf);
- test_memeq(tmp, stuff+12400, 3500);
+ tt_mem_op(tmp,==, stuff+12400, 3500);
fetch_from_buf(tmp, 100, buf);
- test_memeq(tmp, stuff+15900, 10);
+ tt_mem_op(tmp,==, stuff+15900, 10);
buf_free(buf);
@@ -292,7 +292,7 @@ test_buffer_pullup(void *arg)
buf_get_first_chunk_data(buf, &cp, &sz);
tt_ptr_op(cp, !=, NULL);
tt_int_op(sz, ==, 7900);
- test_memeq(cp, stuff+100, 7900);
+ tt_mem_op(cp,==, stuff+100, 7900);
buf_free(buf);
buf = NULL;
@@ -335,14 +335,14 @@ test_buffer_copy(void *arg)
tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
tt_int_op(len, ==, generic_buffer_len(buf2));
generic_buffer_get(buf2, b, len);
- test_mem_op(b, ==, s, len);
+ tt_mem_op(b, ==, s, len);
/* Now free buf2 and retry so we can test allocating */
generic_buffer_free(buf2);
buf2 = NULL;
tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
tt_int_op(len, ==, generic_buffer_len(buf2));
generic_buffer_get(buf2, b, len);
- test_mem_op(b, ==, s, len);
+ tt_mem_op(b, ==, s, len);
/* Clear buf for next test */
generic_buffer_get(buf, b, len);
tt_int_op(generic_buffer_len(buf),==,0);
@@ -362,7 +362,7 @@ test_buffer_copy(void *arg)
for (i = 0; i < 256; ++i) {
generic_buffer_get(buf2, b, len+1);
tt_int_op((unsigned char)b[0],==,i);
- test_mem_op(b+1, ==, s, len);
+ tt_mem_op(b+1, ==, s, len);
}
done:
@@ -410,7 +410,7 @@ test_buffer_ext_or_cmd(void *arg)
tt_ptr_op(NULL, !=, cmd);
tt_int_op(0x1021, ==, cmd->cmd);
tt_int_op(6, ==, cmd->len);
- test_mem_op("abcdef", ==, cmd->body, 6);
+ tt_mem_op("abcdef", ==, cmd->body, 6);
tt_int_op(0, ==, generic_buffer_len(buf));
ext_or_cmd_free(cmd);
cmd = NULL;
@@ -422,7 +422,7 @@ test_buffer_ext_or_cmd(void *arg)
tt_ptr_op(NULL, !=, cmd);
tt_int_op(0xffff, ==, cmd->cmd);
tt_int_op(10, ==, cmd->len);
- test_mem_op("loremipsum", ==, cmd->body, 10);
+ tt_mem_op("loremipsum", ==, cmd->body, 10);
tt_int_op(4, ==, generic_buffer_len(buf));
ext_or_cmd_free(cmd);
cmd = NULL;
@@ -436,7 +436,7 @@ test_buffer_ext_or_cmd(void *arg)
tt_ptr_op(NULL, !=, cmd);
tt_int_op(0x1000, ==, cmd->cmd);
tt_int_op(0xffff, ==, cmd->len);
- test_mem_op(tmp, ==, cmd->body, 65535);
+ tt_mem_op(tmp, ==, cmd->body, 65535);
tt_int_op(0, ==, generic_buffer_len(buf));
ext_or_cmd_free(cmd);
cmd = NULL;
diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c
index d7f60680c2..995e519163 100644
--- a/src/test/test_cell_formats.c
+++ b/src/test/test_cell_formats.c
@@ -35,11 +35,11 @@ test_cfmt_relay_header(void *arg)
tt_int_op(rh.command, ==, 3);
tt_int_op(rh.recognized, ==, 0);
tt_int_op(rh.stream_id, ==, 0x2122);
- test_mem_op(rh.integrity, ==, "ABCD", 4);
+ tt_mem_op(rh.integrity, ==, "ABCD", 4);
tt_int_op(rh.length, ==, 0x103);
relay_header_pack(hdr_out, &rh);
- test_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE);
+ tt_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE);
done:
;
@@ -402,10 +402,10 @@ test_cfmt_create_cells(void *arg)
tt_int_op(CELL_CREATE, ==, cc.cell_type);
tt_int_op(ONION_HANDSHAKE_TYPE_TAP, ==, cc.handshake_type);
tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, ==, cc.handshake_len);
- test_memeq(cc.onionskin, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
+ tt_mem_op(cc.onionskin,==, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
tt_int_op(0, ==, create_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* A valid create_fast cell. */
memset(&cell, 0, sizeof(cell));
@@ -417,10 +417,10 @@ test_cfmt_create_cells(void *arg)
tt_int_op(CELL_CREATE_FAST, ==, cc.cell_type);
tt_int_op(ONION_HANDSHAKE_TYPE_FAST, ==, cc.handshake_type);
tt_int_op(CREATE_FAST_LEN, ==, cc.handshake_len);
- test_memeq(cc.onionskin, b, CREATE_FAST_LEN + 10);
+ tt_mem_op(cc.onionskin,==, b, CREATE_FAST_LEN + 10);
tt_int_op(0, ==, create_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* A valid create2 cell with a TAP payload */
memset(&cell, 0, sizeof(cell));
@@ -433,10 +433,10 @@ test_cfmt_create_cells(void *arg)
tt_int_op(CELL_CREATE2, ==, cc.cell_type);
tt_int_op(ONION_HANDSHAKE_TYPE_TAP, ==, cc.handshake_type);
tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, ==, cc.handshake_len);
- test_memeq(cc.onionskin, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
+ tt_mem_op(cc.onionskin,==, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10);
tt_int_op(0, ==, create_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* A valid create2 cell with an ntor payload */
memset(&cell, 0, sizeof(cell));
@@ -450,10 +450,10 @@ test_cfmt_create_cells(void *arg)
tt_int_op(CELL_CREATE2, ==, cc.cell_type);
tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, ==, cc.handshake_type);
tt_int_op(NTOR_ONIONSKIN_LEN, ==, cc.handshake_len);
- test_memeq(cc.onionskin, b, NTOR_ONIONSKIN_LEN + 10);
+ tt_mem_op(cc.onionskin,==, b, NTOR_ONIONSKIN_LEN + 10);
tt_int_op(0, ==, create_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
#else
tt_int_op(-1, ==, create_cell_parse(&cc, &cell));
#endif
@@ -470,10 +470,10 @@ test_cfmt_create_cells(void *arg)
tt_int_op(CELL_CREATE, ==, cc.cell_type);
tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, ==, cc.handshake_type);
tt_int_op(NTOR_ONIONSKIN_LEN, ==, cc.handshake_len);
- test_memeq(cc.onionskin, b, NTOR_ONIONSKIN_LEN + 10);
+ tt_mem_op(cc.onionskin,==, b, NTOR_ONIONSKIN_LEN + 10);
tt_int_op(0, ==, create_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
#else
tt_int_op(-1, ==, create_cell_parse(&cc, &cell));
#endif
@@ -527,10 +527,10 @@ test_cfmt_created_cells(void *arg)
tt_int_op(0, ==, created_cell_parse(&cc, &cell));
tt_int_op(CELL_CREATED, ==, cc.cell_type);
tt_int_op(TAP_ONIONSKIN_REPLY_LEN, ==, cc.handshake_len);
- test_memeq(cc.reply, b, TAP_ONIONSKIN_REPLY_LEN + 10);
+ tt_mem_op(cc.reply,==, b, TAP_ONIONSKIN_REPLY_LEN + 10);
tt_int_op(0, ==, created_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* A good CREATED_FAST cell */
memset(&cell, 0, sizeof(cell));
@@ -541,10 +541,10 @@ test_cfmt_created_cells(void *arg)
tt_int_op(0, ==, created_cell_parse(&cc, &cell));
tt_int_op(CELL_CREATED_FAST, ==, cc.cell_type);
tt_int_op(CREATED_FAST_LEN, ==, cc.handshake_len);
- test_memeq(cc.reply, b, CREATED_FAST_LEN + 10);
+ tt_mem_op(cc.reply,==, b, CREATED_FAST_LEN + 10);
tt_int_op(0, ==, created_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* A good CREATED2 cell with short reply */
memset(&cell, 0, sizeof(cell));
@@ -556,10 +556,10 @@ test_cfmt_created_cells(void *arg)
tt_int_op(0, ==, created_cell_parse(&cc, &cell));
tt_int_op(CELL_CREATED2, ==, cc.cell_type);
tt_int_op(64, ==, cc.handshake_len);
- test_memeq(cc.reply, b, 80);
+ tt_mem_op(cc.reply,==, b, 80);
tt_int_op(0, ==, created_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* A good CREATED2 cell with maximal reply */
memset(&cell, 0, sizeof(cell));
@@ -571,10 +571,10 @@ test_cfmt_created_cells(void *arg)
tt_int_op(0, ==, created_cell_parse(&cc, &cell));
tt_int_op(CELL_CREATED2, ==, cc.cell_type);
tt_int_op(496, ==, cc.handshake_len);
- test_memeq(cc.reply, b, 496);
+ tt_mem_op(cc.reply,==, b, 496);
tt_int_op(0, ==, created_cell_format(&cell2, &cc));
tt_int_op(cell.command, ==, cell2.command);
- test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE);
+ tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE);
/* Bogus CREATED2 cell: too long! */
memset(&cell, 0, sizeof(cell));
@@ -620,15 +620,15 @@ test_cfmt_extend_cells(void *arg)
tt_str_op("18.244.0.1", ==, fmt_addr(&ec.orport_ipv4.addr));
tt_int_op(258, ==, ec.orport_ipv4.port);
tt_int_op(AF_UNSPEC, ==, tor_addr_family(&ec.orport_ipv6.addr));
- test_memeq(ec.node_id, "electroencephalogram", 20);
+ tt_mem_op(ec.node_id,==, "electroencephalogram", 20);
tt_int_op(cc->cell_type, ==, CELL_CREATE);
tt_int_op(cc->handshake_type, ==, ONION_HANDSHAKE_TYPE_TAP);
tt_int_op(cc->handshake_len, ==, TAP_ONIONSKIN_CHALLENGE_LEN);
- test_memeq(cc->onionskin, b, TAP_ONIONSKIN_CHALLENGE_LEN+20);
+ tt_mem_op(cc->onionskin,==, b, TAP_ONIONSKIN_CHALLENGE_LEN+20);
tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND);
tt_int_op(p2_len, ==, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
- test_memeq(p2, p, RELAY_PAYLOAD_SIZE);
+ tt_mem_op(p2,==, p, RELAY_PAYLOAD_SIZE);
/* Let's do an ntor stuffed in a legacy EXTEND cell */
memset(p, 0, sizeof(p));
@@ -644,15 +644,15 @@ test_cfmt_extend_cells(void *arg)
tt_str_op("18.244.0.1", ==, fmt_addr(&ec.orport_ipv4.addr));
tt_int_op(258, ==, ec.orport_ipv4.port);
tt_int_op(AF_UNSPEC, ==, tor_addr_family(&ec.orport_ipv6.addr));
- test_memeq(ec.node_id, "electroencephalogram", 20);
+ tt_mem_op(ec.node_id,==, "electroencephalogram", 20);
tt_int_op(cc->cell_type, ==, CELL_CREATE2);
tt_int_op(cc->handshake_type, ==, ONION_HANDSHAKE_TYPE_NTOR);
tt_int_op(cc->handshake_len, ==, NTOR_ONIONSKIN_LEN);
- test_memeq(cc->onionskin, b, NTOR_ONIONSKIN_LEN+20);
+ tt_mem_op(cc->onionskin,==, b, NTOR_ONIONSKIN_LEN+20);
tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND);
tt_int_op(p2_len, ==, 26+TAP_ONIONSKIN_CHALLENGE_LEN);
- test_memeq(p2, p, RELAY_PAYLOAD_SIZE);
+ tt_mem_op(p2,==, p, RELAY_PAYLOAD_SIZE);
tt_int_op(0, ==, create_cell_format_relayed(&cell, cc));
/* Now let's do a minimal ntor EXTEND2 cell. */
@@ -673,15 +673,15 @@ test_cfmt_extend_cells(void *arg)
tt_str_op("18.244.0.1", ==, fmt_addr(&ec.orport_ipv4.addr));
tt_int_op(61681, ==, ec.orport_ipv4.port);
tt_int_op(AF_UNSPEC, ==, tor_addr_family(&ec.orport_ipv6.addr));
- test_memeq(ec.node_id, "anarchoindividualist", 20);
+ tt_mem_op(ec.node_id,==, "anarchoindividualist", 20);
tt_int_op(cc->cell_type, ==, CELL_CREATE2);
tt_int_op(cc->handshake_type, ==, ONION_HANDSHAKE_TYPE_NTOR);
tt_int_op(cc->handshake_len, ==, NTOR_ONIONSKIN_LEN);
- test_memeq(cc->onionskin, b, NTOR_ONIONSKIN_LEN+20);
+ tt_mem_op(cc->onionskin,==, b, NTOR_ONIONSKIN_LEN+20);
tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND2);
tt_int_op(p2_len, ==, 35+NTOR_ONIONSKIN_LEN);
- test_memeq(p2, p, RELAY_PAYLOAD_SIZE);
+ tt_mem_op(p2,==, p, RELAY_PAYLOAD_SIZE);
/* Now let's do a fanciful EXTEND2 cell. */
memset(&ec, 0xff, sizeof(ec));
@@ -706,11 +706,11 @@ test_cfmt_extend_cells(void *arg)
tt_int_op(61681, ==, ec.orport_ipv4.port);
tt_str_op("2002::f0:c51e", ==, fmt_addr(&ec.orport_ipv6.addr));
tt_int_op(4370, ==, ec.orport_ipv6.port);
- test_memeq(ec.node_id, "anthropomorphization", 20);
+ tt_mem_op(ec.node_id,==, "anthropomorphization", 20);
tt_int_op(cc->cell_type, ==, CELL_CREATE2);
tt_int_op(cc->handshake_type, ==, 0x105);
tt_int_op(cc->handshake_len, ==, 99);
- test_memeq(cc->onionskin, b, 99+20);
+ tt_mem_op(cc->onionskin,==, b, 99+20);
tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec));
tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND2);
/* We'll generate it minus the IPv6 address and minus the konami code */
@@ -722,7 +722,7 @@ test_cfmt_extend_cells(void *arg)
"0214616e7468726f706f6d6f727068697a6174696f6e"
/* Now the handshake prologue */
"01050063");
- test_memeq(p2+1+8+22+4, b, 99+20);
+ tt_mem_op(p2+1+8+22+4,==, b, 99+20);
tt_int_op(0, ==, create_cell_format_relayed(&cell, cc));
/* == Now try parsing some junk */
@@ -836,11 +836,11 @@ test_cfmt_extended_cells(void *arg)
tt_int_op(RELAY_COMMAND_EXTENDED, ==, ec.cell_type);
tt_int_op(cc->cell_type, ==, CELL_CREATED);
tt_int_op(cc->handshake_len, ==, TAP_ONIONSKIN_REPLY_LEN);
- test_memeq(cc->reply, b, TAP_ONIONSKIN_REPLY_LEN);
+ tt_mem_op(cc->reply,==, b, TAP_ONIONSKIN_REPLY_LEN);
tt_int_op(0, ==, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
tt_int_op(RELAY_COMMAND_EXTENDED, ==, p2_cmd);
tt_int_op(TAP_ONIONSKIN_REPLY_LEN, ==, p2_len);
- test_memeq(p2, p, sizeof(p2));
+ tt_mem_op(p2,==, p, sizeof(p2));
/* Try an EXTENDED2 cell */
memset(&ec, 0xff, sizeof(ec));
@@ -853,11 +853,11 @@ test_cfmt_extended_cells(void *arg)
tt_int_op(RELAY_COMMAND_EXTENDED2, ==, ec.cell_type);
tt_int_op(cc->cell_type, ==, CELL_CREATED2);
tt_int_op(cc->handshake_len, ==, 42);
- test_memeq(cc->reply, b, 42+10);
+ tt_mem_op(cc->reply,==, b, 42+10);
tt_int_op(0, ==, extended_cell_format(&p2_cmd, &p2_len, p2, &ec));
tt_int_op(RELAY_COMMAND_EXTENDED2, ==, p2_cmd);
tt_int_op(2+42, ==, p2_len);
- test_memeq(p2, p, sizeof(p2));
+ tt_mem_op(p2,==, p, sizeof(p2));
/* Try an almost-too-long EXTENDED2 cell */
memcpy(p, "\x01\xf0", 2);
diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c
index 92629823ec..3226f7b973 100644
--- a/src/test/test_cell_queue.c
+++ b/src/test/test_cell_queue.c
@@ -69,15 +69,15 @@ test_cq_manip(void *arg)
pc_tmp = cell_queue_pop(&cq);
tt_int_op(cq.n, ==, 1);
tt_ptr_op(pc_tmp, !=, NULL);
- test_mem_op(pc_tmp->body, ==, "\x12\x34\x56\x78\x0a", 5);
- test_mem_op(pc_tmp->body+5, ==, cell.payload, sizeof(cell.payload));
+ tt_mem_op(pc_tmp->body, ==, "\x12\x34\x56\x78\x0a", 5);
+ tt_mem_op(pc_tmp->body+5, ==, cell.payload, sizeof(cell.payload));
packed_cell_free(pc_tmp);
pc_tmp = cell_queue_pop(&cq);
tt_int_op(cq.n, ==, 0);
tt_ptr_op(pc_tmp, !=, NULL);
- test_mem_op(pc_tmp->body, ==, "\x20\x13\x0a", 3);
- test_mem_op(pc_tmp->body+3, ==, cell.payload, sizeof(cell.payload));
+ tt_mem_op(pc_tmp->body, ==, "\x20\x13\x0a", 3);
+ tt_mem_op(pc_tmp->body+3, ==, cell.payload, sizeof(cell.payload));
packed_cell_free(pc_tmp);
pc_tmp = NULL;
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index b19edd1fd4..e752eaf62a 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -79,9 +79,13 @@ test_clist_maps(void *arg)
memset(&cam, 0, sizeof(cam));
memset(&cdm, 0, sizeof(cdm));
- ch1->cmux = (void*)0x1001;
- ch2->cmux = (void*)0x1002;
- ch3->cmux = (void*)0x1003;
+ tt_assert(ch1);
+ tt_assert(ch2);
+ tt_assert(ch3);
+
+ ch1->cmux = tor_malloc(1);
+ ch2->cmux = tor_malloc(1);
+ ch3->cmux = tor_malloc(1);
or_c1 = or_circuit_new(100, ch2);
tt_assert(or_c1);
@@ -156,6 +160,12 @@ test_clist_maps(void *arg)
circuit_free(TO_CIRCUIT(or_c1));
if (or_c2)
circuit_free(TO_CIRCUIT(or_c2));
+ if (ch1)
+ tor_free(ch1->cmux);
+ if (ch2)
+ tor_free(ch2->cmux);
+ if (ch3)
+ tor_free(ch3->cmux);
tor_free(ch1);
tor_free(ch2);
tor_free(ch3);
@@ -241,7 +251,7 @@ test_rend_token_maps(void *arg)
tt_ptr_op(c3->rendinfo, ==, NULL);
tt_ptr_op(c4->rendinfo, !=, NULL);
- test_mem_op(c4->rendinfo, ==, tok3, REND_TOKEN_LEN);
+ tt_mem_op(c4->rendinfo, ==, tok3, REND_TOKEN_LEN);
/* Now clear c4's cookie. */
circuit_set_intro_point_digest(c4, NULL);
diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c
index b9c0436ebf..a3cacc4cc7 100644
--- a/src/test/test_circuitmux.c
+++ b/src/test/test_circuitmux.c
@@ -65,7 +65,7 @@ test_cmux_destroy_cell_queue(void *arg)
pc = cell_queue_pop(cq);
tt_assert(pc);
- test_mem_op(pc->body, ==, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9);
+ tt_mem_op(pc->body, ==, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9);
packed_cell_free(pc);
pc = NULL;
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 94ac4dca13..6a91453e8c 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -53,57 +53,57 @@ test_config_addressmap(void *arg)
/* MapAddress .invalidwildcard.com .torserver.exit - no match */
strlcpy(address, "www.invalidwildcard.com", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
/* MapAddress *invalidasterisk.com .torserver.exit - no match */
strlcpy(address, "www.invalidasterisk.com", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
/* Where no mapping for FQDN match on top-level domain */
/* MapAddress .google.com .torserver.exit */
strlcpy(address, "reader.google.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "reader.torserver.exit");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "reader.torserver.exit");
/* MapAddress *.yahoo.com *.google.com.torserver.exit */
strlcpy(address, "reader.yahoo.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "reader.google.com.torserver.exit");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "reader.google.com.torserver.exit");
/*MapAddress *.cnn.com www.cnn.com */
strlcpy(address, "cnn.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "www.cnn.com");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "www.cnn.com");
/* MapAddress .cn.com www.cnn.com */
strlcpy(address, "www.cn.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "www.cnn.com");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "www.cnn.com");
/* MapAddress ex.com www.cnn.com - no match */
strlcpy(address, "www.ex.com", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
/* MapAddress ey.com *.cnn.com - invalid expression */
strlcpy(address, "ey.com", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
/* Where mapping for FQDN match on FQDN */
strlcpy(address, "www.google.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "3.3.3.3");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "3.3.3.3");
strlcpy(address, "www.torproject.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "1.1.1.1");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "1.1.1.1");
strlcpy(address, "other.torproject.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "this.torproject.org.otherserver.exit");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "this.torproject.org.otherserver.exit");
strlcpy(address, "test.torproject.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "2.2.2.2");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "2.2.2.2");
/* Test a chain of address mappings and the order in which they were added:
"MapAddress www.example.org 4.4.4.4"
@@ -111,17 +111,17 @@ test_config_addressmap(void *arg)
"MapAddress 4.4.4.4 5.5.5.5"
*/
strlcpy(address, "www.example.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "5.5.5.5");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "5.5.5.5");
/* Test infinite address mapping results in no change */
strlcpy(address, "www.infiniteloop.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "www.infiniteloop.org");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "www.infiniteloop.org");
/* Test we don't find false positives */
strlcpy(address, "www.example.com", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
/* Test top-level-domain matching a bit harder */
config_free_lines(get_options_mutable()->AddressMap);
@@ -134,24 +134,24 @@ test_config_addressmap(void *arg)
config_register_addressmaps(get_options());
strlcpy(address, "www.abc.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "www.abc.torserver.exit");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "www.abc.torserver.exit");
strlcpy(address, "www.def.com", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "www.def.torserver.exit");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "www.def.torserver.exit");
strlcpy(address, "www.torproject.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "1.1.1.1");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "1.1.1.1");
strlcpy(address, "test.torproject.org", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "1.1.1.1");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "1.1.1.1");
strlcpy(address, "torproject.net", sizeof(address));
- test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
- test_streq(address, "2.2.2.2");
+ tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_str_op(address,==, "2.2.2.2");
/* We don't support '*' as a mapping directive */
config_free_lines(get_options_mutable()->AddressMap);
@@ -161,13 +161,13 @@ test_config_addressmap(void *arg)
config_register_addressmaps(get_options());
strlcpy(address, "www.abc.com", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
strlcpy(address, "www.def.net", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
strlcpy(address, "www.torproject.org", sizeof(address));
- test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
+ tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL));
#undef addressmap_rewrite
@@ -184,7 +184,7 @@ is_private_dir(const char* path)
if (r) {
return 0;
}
-#if !defined (_WIN32) || defined (WINCE)
+#if !defined (_WIN32)
if ((st.st_mode & (S_IFDIR | 0777)) != (S_IFDIR | 0700)) {
return 0;
}
@@ -201,7 +201,7 @@ test_config_check_or_create_data_subdir(void *arg)
char *subpath;
struct stat st;
int r;
-#if !defined (_WIN32) || defined (WINCE)
+#if !defined (_WIN32)
unsigned group_permission;
#endif
(void)arg;
@@ -210,7 +210,7 @@ test_config_check_or_create_data_subdir(void *arg)
datadir = options->DataDirectory = tor_strdup(get_fname("datadir-0"));
subpath = get_datadir_fname(subdir);
-#if defined (_WIN32) && !defined (WINCE)
+#if defined (_WIN32)
tt_int_op(mkdir(options->DataDirectory), ==, 0);
#else
tt_int_op(mkdir(options->DataDirectory, 0700), ==, 0);
@@ -220,20 +220,20 @@ test_config_check_or_create_data_subdir(void *arg)
// The subdirectory shouldn't exist yet,
// but should be created by the call to check_or_create_data_subdir.
- test_assert(r && (errno == ENOENT));
- test_assert(!check_or_create_data_subdir(subdir));
- test_assert(is_private_dir(subpath));
+ tt_assert(r && (errno == ENOENT));
+ tt_assert(!check_or_create_data_subdir(subdir));
+ tt_assert(is_private_dir(subpath));
// The check should return 0, if the directory already exists
// and is private to the user.
- test_assert(!check_or_create_data_subdir(subdir));
+ tt_assert(!check_or_create_data_subdir(subdir));
r = stat(subpath, &st);
if (r) {
tt_abort_perror("stat");
}
-#if !defined (_WIN32) || defined (WINCE)
+#if !defined (_WIN32)
group_permission = st.st_mode | 0070;
r = chmod(subpath, group_permission);
@@ -243,9 +243,9 @@ test_config_check_or_create_data_subdir(void *arg)
// If the directory exists, but its mode is too permissive
// a call to check_or_create_data_subdir should reset the mode.
- test_assert(!is_private_dir(subpath));
- test_assert(!check_or_create_data_subdir(subdir));
- test_assert(is_private_dir(subpath));
+ tt_assert(!is_private_dir(subpath));
+ tt_assert(!check_or_create_data_subdir(subdir));
+ tt_assert(is_private_dir(subpath));
#endif
done:
@@ -284,27 +284,27 @@ test_config_write_to_data_subdir(void *arg)
datadir = options->DataDirectory = tor_strdup(get_fname("datadir-1"));
filepath = get_datadir_fname2(subdir, fname);
-#if defined (_WIN32) && !defined (WINCE)
+#if defined (_WIN32)
tt_int_op(mkdir(options->DataDirectory), ==, 0);
#else
tt_int_op(mkdir(options->DataDirectory, 0700), ==, 0);
#endif
// Write attempt shoudl fail, if subdirectory doesn't exist.
- test_assert(write_to_data_subdir(subdir, fname, str, NULL));
- test_assert(! check_or_create_data_subdir(subdir));
+ tt_assert(write_to_data_subdir(subdir, fname, str, NULL));
+ tt_assert(! check_or_create_data_subdir(subdir));
// Content of file after write attempt should be
// equal to the original string.
- test_assert(!write_to_data_subdir(subdir, fname, str, NULL));
+ tt_assert(!write_to_data_subdir(subdir, fname, str, NULL));
cp = read_file_to_str(filepath, 0, NULL);
- test_streq(cp, str);
+ tt_str_op(cp,==, str);
tor_free(cp);
// A second write operation should overwrite the old content.
- test_assert(!write_to_data_subdir(subdir, fname, str, NULL));
+ tt_assert(!write_to_data_subdir(subdir, fname, str, NULL));
cp = read_file_to_str(filepath, 0, NULL);
- test_streq(cp, str);
+ tt_str_op(cp,==, str);
tor_free(cp);
done:
@@ -325,48 +325,48 @@ good_bridge_line_test(const char *string, const char *test_addrport,
{
char *tmp = NULL;
bridge_line_t *bridge_line = parse_bridge_line(string);
- test_assert(bridge_line);
+ tt_assert(bridge_line);
/* test addrport */
tmp = tor_strdup(fmt_addrport(&bridge_line->addr, bridge_line->port));
- test_streq(test_addrport, tmp);
+ tt_str_op(test_addrport,==, tmp);
tor_free(tmp);
/* If we were asked to validate a digest, but we did not get a
digest after parsing, we failed. */
if (test_digest && tor_digest_is_zero(bridge_line->digest))
- test_assert(0);
+ tt_assert(0);
/* If we were not asked to validate a digest, and we got a digest
after parsing, we failed again. */
if (!test_digest && !tor_digest_is_zero(bridge_line->digest))
- test_assert(0);
+ tt_assert(0);
/* If we were asked to validate a digest, and we got a digest after
parsing, make sure it's correct. */
if (test_digest) {
tmp = tor_strdup(hex_str(bridge_line->digest, DIGEST_LEN));
tor_strlower(tmp);
- test_streq(test_digest, tmp);
+ tt_str_op(test_digest,==, tmp);
tor_free(tmp);
}
/* If we were asked to validate a transport name, make sure tha it
matches with the transport name that was parsed. */
if (test_transport && !bridge_line->transport_name)
- test_assert(0);
+ tt_assert(0);
if (!test_transport && bridge_line->transport_name)
- test_assert(0);
+ tt_assert(0);
if (test_transport)
- test_streq(test_transport, bridge_line->transport_name);
+ tt_str_op(test_transport,==, bridge_line->transport_name);
/* Validate the SOCKS argument smartlist. */
if (test_socks_args && !bridge_line->socks_args)
- test_assert(0);
+ tt_assert(0);
if (!test_socks_args && bridge_line->socks_args)
- test_assert(0);
+ tt_assert(0);
if (test_socks_args)
- test_assert(smartlist_strings_eq(test_socks_args,
+ tt_assert(smartlist_strings_eq(test_socks_args,
bridge_line->socks_args));
done:
@@ -382,7 +382,7 @@ bad_bridge_line_test(const char *string)
bridge_line_t *bridge_line = parse_bridge_line(string);
if (bridge_line)
TT_FAIL(("%s was supposed to fail, but it didn't.", string));
- test_assert(!bridge_line);
+ tt_assert(!bridge_line);
done:
bridge_line_free(bridge_line);
@@ -490,18 +490,18 @@ test_config_parse_transport_options_line(void *arg)
{ /* too small line */
options_sl = get_options_from_transport_options_line("valley", NULL);
- test_assert(!options_sl);
+ tt_assert(!options_sl);
}
{ /* no k=v values */
options_sl = get_options_from_transport_options_line("hit it!", NULL);
- test_assert(!options_sl);
+ tt_assert(!options_sl);
}
{ /* correct line, but wrong transport specified */
options_sl =
get_options_from_transport_options_line("trebuchet k=v", "rook");
- test_assert(!options_sl);
+ tt_assert(!options_sl);
}
{ /* correct -- no transport specified */
@@ -512,8 +512,8 @@ test_config_parse_transport_options_line(void *arg)
options_sl =
get_options_from_transport_options_line("rook ladi=dadi weliketo=party",
NULL);
- test_assert(options_sl);
- test_assert(smartlist_strings_eq(options_sl, sl_tmp));
+ tt_assert(options_sl);
+ tt_assert(smartlist_strings_eq(options_sl, sl_tmp));
SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
smartlist_free(sl_tmp);
@@ -531,8 +531,8 @@ test_config_parse_transport_options_line(void *arg)
options_sl =
get_options_from_transport_options_line("rook ladi=dadi weliketo=party",
"rook");
- test_assert(options_sl);
- test_assert(smartlist_strings_eq(options_sl, sl_tmp));
+ tt_assert(options_sl);
+ tt_assert(smartlist_strings_eq(options_sl, sl_tmp));
SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
smartlist_free(sl_tmp);
sl_tmp = NULL;
@@ -576,7 +576,7 @@ test_config_fix_my_family(void *arg)
TT_FAIL(("options_validate failed: %s", err));
}
- test_streq(options->MyFamily, "$1111111111111111111111111111111111111111, "
+ tt_str_op(options->MyFamily,==, "$1111111111111111111111111111111111111111, "
"$1111111111111111111111111111111111111112, "
"$1111111111111111111111111111111111111113");
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
index 067c4c1907..24211dd580 100644
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@ -29,7 +29,7 @@ compare_strs_for_bsearch_(const void *a, const void **b)
/** Helper: return a tristate based on comparing the strings in *<b>a</b> and
* *<b>b</b>, excluding a's first character, and ignoring case. */
static int
-compare_without_first_ch_(const void *a, const void **b)
+cmp_without_first_(const void *a, const void **b)
{
const char *s1 = a, *s2 = *b;
return strcasecmp(s1+1, s2);
@@ -37,237 +37,256 @@ compare_without_first_ch_(const void *a, const void **b)
/** Run unit tests for basic dynamic-sized array functionality. */
static void
-test_container_smartlist_basic(void)
+test_container_smartlist_basic(void *arg)
{
smartlist_t *sl;
+ char *v0 = tor_strdup("v0");
+ char *v1 = tor_strdup("v1");
+ char *v2 = tor_strdup("v2");
+ char *v3 = tor_strdup("v3");
+ char *v4 = tor_strdup("v4");
+ char *v22 = tor_strdup("v22");
+ char *v99 = tor_strdup("v99");
+ char *v555 = tor_strdup("v555");
/* XXXX test sort_digests, uniq_strings, uniq_digests */
/* Test smartlist add, del_keeporder, insert, get. */
+ (void)arg;
sl = smartlist_new();
- smartlist_add(sl, (void*)1);
- smartlist_add(sl, (void*)2);
- smartlist_add(sl, (void*)3);
- smartlist_add(sl, (void*)4);
+ smartlist_add(sl, v1);
+ smartlist_add(sl, v2);
+ smartlist_add(sl, v3);
+ smartlist_add(sl, v4);
smartlist_del_keeporder(sl, 1);
- smartlist_insert(sl, 1, (void*)22);
- smartlist_insert(sl, 0, (void*)0);
- smartlist_insert(sl, 5, (void*)555);
- test_eq_ptr((void*)0, smartlist_get(sl,0));
- test_eq_ptr((void*)1, smartlist_get(sl,1));
- test_eq_ptr((void*)22, smartlist_get(sl,2));
- test_eq_ptr((void*)3, smartlist_get(sl,3));
- test_eq_ptr((void*)4, smartlist_get(sl,4));
- test_eq_ptr((void*)555, smartlist_get(sl,5));
+ smartlist_insert(sl, 1, v22);
+ smartlist_insert(sl, 0, v0);
+ smartlist_insert(sl, 5, v555);
+ tt_ptr_op(v0,==, smartlist_get(sl,0));
+ tt_ptr_op(v1,==, smartlist_get(sl,1));
+ tt_ptr_op(v22,==, smartlist_get(sl,2));
+ tt_ptr_op(v3,==, smartlist_get(sl,3));
+ tt_ptr_op(v4,==, smartlist_get(sl,4));
+ tt_ptr_op(v555,==, smartlist_get(sl,5));
/* Try deleting in the middle. */
smartlist_del(sl, 1);
- test_eq_ptr((void*)555, smartlist_get(sl, 1));
+ tt_ptr_op(v555,==, smartlist_get(sl, 1));
/* Try deleting at the end. */
smartlist_del(sl, 4);
- test_eq(4, smartlist_len(sl));
+ tt_int_op(4,==, smartlist_len(sl));
/* test isin. */
- test_assert(smartlist_contains(sl, (void*)3));
- test_assert(!smartlist_contains(sl, (void*)99));
+ tt_assert(smartlist_contains(sl, v3));
+ tt_assert(!smartlist_contains(sl, v99));
done:
smartlist_free(sl);
+ tor_free(v0);
+ tor_free(v1);
+ tor_free(v2);
+ tor_free(v3);
+ tor_free(v4);
+ tor_free(v22);
+ tor_free(v99);
+ tor_free(v555);
}
/** Run unit tests for smartlist-of-strings functionality. */
static void
-test_container_smartlist_strings(void)
+test_container_smartlist_strings(void *arg)
{
smartlist_t *sl = smartlist_new();
char *cp=NULL, *cp_alloc=NULL;
size_t sz;
/* Test split and join */
- test_eq(0, smartlist_len(sl));
+ (void)arg;
+ tt_int_op(0,==, smartlist_len(sl));
smartlist_split_string(sl, "abc", ":", 0, 0);
- test_eq(1, smartlist_len(sl));
- test_streq("abc", smartlist_get(sl, 0));
+ tt_int_op(1,==, smartlist_len(sl));
+ tt_str_op("abc",==, smartlist_get(sl, 0));
smartlist_split_string(sl, "a::bc::", "::", 0, 0);
- test_eq(4, smartlist_len(sl));
- test_streq("a", smartlist_get(sl, 1));
- test_streq("bc", smartlist_get(sl, 2));
- test_streq("", smartlist_get(sl, 3));
+ tt_int_op(4,==, smartlist_len(sl));
+ tt_str_op("a",==, smartlist_get(sl, 1));
+ tt_str_op("bc",==, smartlist_get(sl, 2));
+ tt_str_op("",==, smartlist_get(sl, 3));
cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
- test_streq(cp_alloc, "abcabc");
+ tt_str_op(cp_alloc,==, "abcabc");
tor_free(cp_alloc);
cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
- test_streq(cp_alloc, "abc!a!bc!");
+ tt_str_op(cp_alloc,==, "abc!a!bc!");
tor_free(cp_alloc);
cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
- test_streq(cp_alloc, "abcXYaXYbcXY");
+ tt_str_op(cp_alloc,==, "abcXYaXYbcXY");
tor_free(cp_alloc);
cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
- test_streq(cp_alloc, "abcXYaXYbcXYXY");
+ tt_str_op(cp_alloc,==, "abcXYaXYbcXYXY");
tor_free(cp_alloc);
cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
- test_streq(cp_alloc, "abcabc");
+ tt_str_op(cp_alloc,==, "abcabc");
tor_free(cp_alloc);
smartlist_split_string(sl, "/def/ /ghijk", "/", 0, 0);
- test_eq(8, smartlist_len(sl));
- test_streq("", smartlist_get(sl, 4));
- test_streq("def", smartlist_get(sl, 5));
- test_streq(" ", smartlist_get(sl, 6));
- test_streq("ghijk", smartlist_get(sl, 7));
+ tt_int_op(8,==, smartlist_len(sl));
+ tt_str_op("",==, smartlist_get(sl, 4));
+ tt_str_op("def",==, smartlist_get(sl, 5));
+ tt_str_op(" ",==, smartlist_get(sl, 6));
+ tt_str_op("ghijk",==, smartlist_get(sl, 7));
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
- test_eq(3, smartlist_len(sl));
- test_streq("a", smartlist_get(sl,0));
- test_streq("bbd", smartlist_get(sl,1));
- test_streq("cdef", smartlist_get(sl,2));
+ tt_int_op(3,==, smartlist_len(sl));
+ tt_str_op("a",==, smartlist_get(sl,0));
+ tt_str_op("bbd",==, smartlist_get(sl,1));
+ tt_str_op("cdef",==, smartlist_get(sl,2));
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
SPLIT_SKIP_SPACE, 0);
- test_eq(8, smartlist_len(sl));
- test_streq("z", smartlist_get(sl,3));
- test_streq("zhasd", smartlist_get(sl,4));
- test_streq("", smartlist_get(sl,5));
- test_streq("bnud", smartlist_get(sl,6));
- test_streq("", smartlist_get(sl,7));
+ tt_int_op(8,==, smartlist_len(sl));
+ tt_str_op("z",==, smartlist_get(sl,3));
+ tt_str_op("zhasd",==, smartlist_get(sl,4));
+ tt_str_op("",==, smartlist_get(sl,5));
+ tt_str_op("bnud",==, smartlist_get(sl,6));
+ tt_str_op("",==, smartlist_get(sl,7));
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
smartlist_split_string(sl, " ab\tc \td ef ", NULL,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(4, smartlist_len(sl));
- test_streq("ab", smartlist_get(sl,0));
- test_streq("c", smartlist_get(sl,1));
- test_streq("d", smartlist_get(sl,2));
- test_streq("ef", smartlist_get(sl,3));
+ tt_int_op(4,==, smartlist_len(sl));
+ tt_str_op("ab",==, smartlist_get(sl,0));
+ tt_str_op("c",==, smartlist_get(sl,1));
+ tt_str_op("d",==, smartlist_get(sl,2));
+ tt_str_op("ef",==, smartlist_get(sl,3));
smartlist_split_string(sl, "ghi\tj", NULL,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(6, smartlist_len(sl));
- test_streq("ghi", smartlist_get(sl,4));
- test_streq("j", smartlist_get(sl,5));
+ tt_int_op(6,==, smartlist_len(sl));
+ tt_str_op("ghi",==, smartlist_get(sl,4));
+ tt_str_op("j",==, smartlist_get(sl,5));
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
- test_streq(cp_alloc, "");
+ tt_str_op(cp_alloc,==, "");
tor_free(cp_alloc);
cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
- test_streq(cp_alloc, "XY");
+ tt_str_op(cp_alloc,==, "XY");
tor_free(cp_alloc);
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(3, smartlist_len(sl));
- test_streq("z", smartlist_get(sl, 0));
- test_streq("zhasd", smartlist_get(sl, 1));
- test_streq("bnud", smartlist_get(sl, 2));
+ tt_int_op(3,==, smartlist_len(sl));
+ tt_str_op("z",==, smartlist_get(sl, 0));
+ tt_str_op("zhasd",==, smartlist_get(sl, 1));
+ tt_str_op("bnud",==, smartlist_get(sl, 2));
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
- test_eq(5, smartlist_len(sl));
- test_streq("z", smartlist_get(sl, 3));
- test_streq("zhasd <> <> bnud<>", smartlist_get(sl, 4));
+ tt_int_op(5,==, smartlist_len(sl));
+ tt_str_op("z",==, smartlist_get(sl, 3));
+ tt_str_op("zhasd <> <> bnud<>",==, smartlist_get(sl, 4));
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
smartlist_split_string(sl, "abcd\n", "\n",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(1, smartlist_len(sl));
- test_streq("abcd", smartlist_get(sl, 0));
+ tt_int_op(1,==, smartlist_len(sl));
+ tt_str_op("abcd",==, smartlist_get(sl, 0));
smartlist_split_string(sl, "efgh", "\n",
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- test_eq(2, smartlist_len(sl));
- test_streq("efgh", smartlist_get(sl, 1));
+ tt_int_op(2,==, smartlist_len(sl));
+ tt_str_op("efgh",==, smartlist_get(sl, 1));
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
/* Test swapping, shuffling, and sorting. */
smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
- test_eq(7, smartlist_len(sl));
+ tt_int_op(7,==, smartlist_len(sl));
smartlist_sort(sl, compare_strs_);
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"and,arma,by,nickm,onion,router,the");
+ tt_str_op(cp_alloc,==, "and,arma,by,nickm,onion,router,the");
tor_free(cp_alloc);
smartlist_swap(sl, 1, 5);
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"and,router,by,nickm,onion,arma,the");
+ tt_str_op(cp_alloc,==, "and,router,by,nickm,onion,arma,the");
tor_free(cp_alloc);
smartlist_shuffle(sl);
- test_eq(7, smartlist_len(sl));
- test_assert(smartlist_contains_string(sl, "and"));
- test_assert(smartlist_contains_string(sl, "router"));
- test_assert(smartlist_contains_string(sl, "by"));
- test_assert(smartlist_contains_string(sl, "nickm"));
- test_assert(smartlist_contains_string(sl, "onion"));
- test_assert(smartlist_contains_string(sl, "arma"));
- test_assert(smartlist_contains_string(sl, "the"));
+ tt_int_op(7,==, smartlist_len(sl));
+ tt_assert(smartlist_contains_string(sl, "and"));
+ tt_assert(smartlist_contains_string(sl, "router"));
+ tt_assert(smartlist_contains_string(sl, "by"));
+ tt_assert(smartlist_contains_string(sl, "nickm"));
+ tt_assert(smartlist_contains_string(sl, "onion"));
+ tt_assert(smartlist_contains_string(sl, "arma"));
+ tt_assert(smartlist_contains_string(sl, "the"));
/* Test bsearch. */
smartlist_sort(sl, compare_strs_);
- test_streq("nickm", smartlist_bsearch(sl, "zNicKM",
- compare_without_first_ch_));
- test_streq("and", smartlist_bsearch(sl, " AND", compare_without_first_ch_));
- test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", compare_without_first_ch_));
+ tt_str_op("nickm",==, smartlist_bsearch(sl, "zNicKM",
+ cmp_without_first_));
+ tt_str_op("and",==,
+ smartlist_bsearch(sl, " AND", cmp_without_first_));
+ tt_ptr_op(NULL,==, smartlist_bsearch(sl, " ANz", cmp_without_first_));
/* Test bsearch_idx */
{
int f;
smartlist_t *tmp = NULL;
- test_eq(0, smartlist_bsearch_idx(sl," aaa",compare_without_first_ch_,&f));
- test_eq(f, 0);
- test_eq(0, smartlist_bsearch_idx(sl," and",compare_without_first_ch_,&f));
- test_eq(f, 1);
- test_eq(1, smartlist_bsearch_idx(sl," arm",compare_without_first_ch_,&f));
- test_eq(f, 0);
- test_eq(1, smartlist_bsearch_idx(sl," arma",compare_without_first_ch_,&f));
- test_eq(f, 1);
- test_eq(2, smartlist_bsearch_idx(sl," armb",compare_without_first_ch_,&f));
- test_eq(f, 0);
- test_eq(7, smartlist_bsearch_idx(sl," zzzz",compare_without_first_ch_,&f));
- test_eq(f, 0);
+ tt_int_op(0,==,smartlist_bsearch_idx(sl," aaa",cmp_without_first_,&f));
+ tt_int_op(f,==, 0);
+ tt_int_op(0,==, smartlist_bsearch_idx(sl," and",cmp_without_first_,&f));
+ tt_int_op(f,==, 1);
+ tt_int_op(1,==, smartlist_bsearch_idx(sl," arm",cmp_without_first_,&f));
+ tt_int_op(f,==, 0);
+ tt_int_op(1,==, smartlist_bsearch_idx(sl," arma",cmp_without_first_,&f));
+ tt_int_op(f,==, 1);
+ tt_int_op(2,==, smartlist_bsearch_idx(sl," armb",cmp_without_first_,&f));
+ tt_int_op(f,==, 0);
+ tt_int_op(7,==, smartlist_bsearch_idx(sl," zzzz",cmp_without_first_,&f));
+ tt_int_op(f,==, 0);
/* Test trivial cases for list of length 0 or 1 */
tmp = smartlist_new();
- test_eq(0, smartlist_bsearch_idx(tmp, "foo",
+ tt_int_op(0,==, smartlist_bsearch_idx(tmp, "foo",
compare_strs_for_bsearch_, &f));
- test_eq(f, 0);
+ tt_int_op(f,==, 0);
smartlist_insert(tmp, 0, (void *)("bar"));
- test_eq(1, smartlist_bsearch_idx(tmp, "foo",
+ tt_int_op(1,==, smartlist_bsearch_idx(tmp, "foo",
compare_strs_for_bsearch_, &f));
- test_eq(f, 0);
- test_eq(0, smartlist_bsearch_idx(tmp, "aaa",
+ tt_int_op(f,==, 0);
+ tt_int_op(0,==, smartlist_bsearch_idx(tmp, "aaa",
compare_strs_for_bsearch_, &f));
- test_eq(f, 0);
- test_eq(0, smartlist_bsearch_idx(tmp, "bar",
+ tt_int_op(f,==, 0);
+ tt_int_op(0,==, smartlist_bsearch_idx(tmp, "bar",
compare_strs_for_bsearch_, &f));
- test_eq(f, 1);
+ tt_int_op(f,==, 1);
/* ... and one for length 2 */
smartlist_insert(tmp, 1, (void *)("foo"));
- test_eq(1, smartlist_bsearch_idx(tmp, "foo",
+ tt_int_op(1,==, smartlist_bsearch_idx(tmp, "foo",
compare_strs_for_bsearch_, &f));
- test_eq(f, 1);
- test_eq(2, smartlist_bsearch_idx(tmp, "goo",
+ tt_int_op(f,==, 1);
+ tt_int_op(2,==, smartlist_bsearch_idx(tmp, "goo",
compare_strs_for_bsearch_, &f));
- test_eq(f, 0);
+ tt_int_op(f,==, 0);
smartlist_free(tmp);
}
/* Test reverse() and pop_last() */
smartlist_reverse(sl);
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc,"the,router,onion,nickm,by,arma,and");
+ tt_str_op(cp_alloc,==, "the,router,onion,nickm,by,arma,and");
tor_free(cp_alloc);
cp_alloc = smartlist_pop_last(sl);
- test_streq(cp_alloc, "and");
+ tt_str_op(cp_alloc,==, "and");
tor_free(cp_alloc);
- test_eq(smartlist_len(sl), 6);
+ tt_int_op(smartlist_len(sl),==, 6);
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
cp_alloc = smartlist_pop_last(sl);
- test_eq_ptr(cp_alloc, NULL);
+ tt_ptr_op(cp_alloc,==, NULL);
/* Test uniq() */
smartlist_split_string(sl,
@@ -276,16 +295,16 @@ test_container_smartlist_strings(void)
smartlist_sort(sl, compare_strs_);
smartlist_uniq(sl, compare_strs_, tor_free_);
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc, "50,a,canal,man,noon,panama,plan,radar");
+ tt_str_op(cp_alloc,==, "50,a,canal,man,noon,panama,plan,radar");
tor_free(cp_alloc);
/* Test contains_string, contains_string_case and contains_int_as_string */
- test_assert(smartlist_contains_string(sl, "noon"));
- test_assert(!smartlist_contains_string(sl, "noonoon"));
- test_assert(smartlist_contains_string_case(sl, "nOOn"));
- test_assert(!smartlist_contains_string_case(sl, "nooNooN"));
- test_assert(smartlist_contains_int_as_string(sl, 50));
- test_assert(!smartlist_contains_int_as_string(sl, 60));
+ tt_assert(smartlist_contains_string(sl, "noon"));
+ tt_assert(!smartlist_contains_string(sl, "noonoon"));
+ tt_assert(smartlist_contains_string_case(sl, "nOOn"));
+ tt_assert(!smartlist_contains_string_case(sl, "nooNooN"));
+ tt_assert(smartlist_contains_int_as_string(sl, 50));
+ tt_assert(!smartlist_contains_int_as_string(sl, 60));
/* Test smartlist_choose */
{
@@ -293,7 +312,7 @@ test_container_smartlist_strings(void)
int allsame = 1;
int allin = 1;
void *first = smartlist_choose(sl);
- test_assert(smartlist_contains(sl, first));
+ tt_assert(smartlist_contains(sl, first));
for (i = 0; i < 100; ++i) {
void *second = smartlist_choose(sl);
if (second != first)
@@ -301,8 +320,8 @@ test_container_smartlist_strings(void)
if (!smartlist_contains(sl, second))
allin = 0;
}
- test_assert(!allsame);
- test_assert(allin);
+ tt_assert(!allsame);
+ tt_assert(allin);
}
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
smartlist_clear(sl);
@@ -312,17 +331,17 @@ test_container_smartlist_strings(void)
"Some say the Earth will end in ice and some in fire",
" ", 0, 0);
cp = smartlist_get(sl, 4);
- test_streq(cp, "will");
+ tt_str_op(cp,==, "will");
smartlist_add(sl, cp);
smartlist_remove(sl, cp);
tor_free(cp);
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
- test_streq(cp_alloc, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
+ tt_str_op(cp_alloc,==, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
tor_free(cp_alloc);
smartlist_string_remove(sl, "in");
cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
- test_streq(cp_alloc, "Some+say+the+Earth+fire+end+some+ice+and");
- test_eq((int)sz, 40);
+ tt_str_op(cp_alloc,==, "Some+say+the+Earth+fire+end+some+ice+and");
+ tt_int_op((int)sz,==, 40);
done:
@@ -333,7 +352,7 @@ test_container_smartlist_strings(void)
/** Run unit tests for smartlist set manipulation functions. */
static void
-test_container_smartlist_overlap(void)
+test_container_smartlist_overlap(void *arg)
{
smartlist_t *sl = smartlist_new();
smartlist_t *ints = smartlist_new();
@@ -341,6 +360,7 @@ test_container_smartlist_overlap(void)
smartlist_t *evens = smartlist_new();
smartlist_t *primes = smartlist_new();
int i;
+ (void)arg;
for (i=1; i < 10; i += 2)
smartlist_add(odds, (void*)(uintptr_t)i);
for (i=0; i < 10; i += 2)
@@ -349,7 +369,7 @@ test_container_smartlist_overlap(void)
/* add_all */
smartlist_add_all(ints, odds);
smartlist_add_all(ints, evens);
- test_eq(smartlist_len(ints), 10);
+ tt_int_op(smartlist_len(ints),==, 10);
smartlist_add(primes, (void*)2);
smartlist_add(primes, (void*)3);
@@ -357,24 +377,24 @@ test_container_smartlist_overlap(void)
smartlist_add(primes, (void*)7);
/* overlap */
- test_assert(smartlist_overlap(ints, odds));
- test_assert(smartlist_overlap(odds, primes));
- test_assert(smartlist_overlap(evens, primes));
- test_assert(!smartlist_overlap(odds, evens));
+ tt_assert(smartlist_overlap(ints, odds));
+ tt_assert(smartlist_overlap(odds, primes));
+ tt_assert(smartlist_overlap(evens, primes));
+ tt_assert(!smartlist_overlap(odds, evens));
/* intersect */
smartlist_add_all(sl, odds);
smartlist_intersect(sl, primes);
- test_eq(smartlist_len(sl), 3);
- test_assert(smartlist_contains(sl, (void*)3));
- test_assert(smartlist_contains(sl, (void*)5));
- test_assert(smartlist_contains(sl, (void*)7));
+ tt_int_op(smartlist_len(sl),==, 3);
+ tt_assert(smartlist_contains(sl, (void*)3));
+ tt_assert(smartlist_contains(sl, (void*)5));
+ tt_assert(smartlist_contains(sl, (void*)7));
/* subtract */
smartlist_add_all(sl, primes);
smartlist_subtract(sl, odds);
- test_eq(smartlist_len(sl), 1);
- test_assert(smartlist_contains(sl, (void*)2));
+ tt_int_op(smartlist_len(sl),==, 1);
+ tt_assert(smartlist_contains(sl, (void*)2));
done:
smartlist_free(odds);
@@ -386,31 +406,32 @@ test_container_smartlist_overlap(void)
/** Run unit tests for smartlist-of-digests functions. */
static void
-test_container_smartlist_digests(void)
+test_container_smartlist_digests(void *arg)
{
smartlist_t *sl = smartlist_new();
/* contains_digest */
+ (void)arg;
smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN));
smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
- test_eq(0, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA"));
- test_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA"));
- test_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA"));
- test_eq(0, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA"));
+ tt_int_op(0,==, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA"));
+ tt_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA"));
+ tt_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA"));
+ tt_int_op(0,==, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA"));
/* sort digests */
smartlist_sort_digests(sl);
- test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
- test_memeq(smartlist_get(sl, 1), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
- test_memeq(smartlist_get(sl, 2), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
- test_eq(3, smartlist_len(sl));
+ tt_mem_op(smartlist_get(sl, 0),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
+ tt_mem_op(smartlist_get(sl, 1),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
+ tt_mem_op(smartlist_get(sl, 2),==, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
+ tt_int_op(3,==, smartlist_len(sl));
/* uniq_digests */
smartlist_uniq_digests(sl);
- test_eq(2, smartlist_len(sl));
- test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
- test_memeq(smartlist_get(sl, 1), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
+ tt_int_op(2,==, smartlist_len(sl));
+ tt_mem_op(smartlist_get(sl, 0),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
+ tt_mem_op(smartlist_get(sl, 1),==, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
done:
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
@@ -419,13 +440,14 @@ test_container_smartlist_digests(void)
/** Run unit tests for concatenate-a-smartlist-of-strings functions. */
static void
-test_container_smartlist_join(void)
+test_container_smartlist_join(void *arg)
{
smartlist_t *sl = smartlist_new();
smartlist_t *sl2 = smartlist_new(), *sl3 = smartlist_new(),
*sl4 = smartlist_new();
char *joined=NULL;
/* unique, sorted. */
+ (void)arg;
smartlist_split_string(sl,
"Abashments Ambush Anchorman Bacon Banks Borscht "
"Bunks Inhumane Insurance Knish Know Manners "
@@ -441,21 +463,21 @@ test_container_smartlist_join(void)
sl2, char *, cp2,
strcmp(cp1,cp2),
smartlist_add(sl3, cp2)) {
- test_streq(cp1, cp2);
+ tt_str_op(cp1,==, cp2);
smartlist_add(sl4, cp1);
} SMARTLIST_FOREACH_JOIN_END(cp1, cp2);
SMARTLIST_FOREACH(sl3, const char *, cp,
- test_assert(smartlist_contains(sl2, cp) &&
+ tt_assert(smartlist_contains(sl2, cp) &&
!smartlist_contains_string(sl, cp)));
SMARTLIST_FOREACH(sl4, const char *, cp,
- test_assert(smartlist_contains(sl, cp) &&
+ tt_assert(smartlist_contains(sl, cp) &&
smartlist_contains_string(sl2, cp)));
joined = smartlist_join_strings(sl3, ",", 0, NULL);
- test_streq(joined, "Anemias,Anemias,Crossbowmen,Work");
+ tt_str_op(joined,==, "Anemias,Anemias,Crossbowmen,Work");
tor_free(joined);
joined = smartlist_join_strings(sl4, ",", 0, NULL);
- test_streq(joined, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
+ tt_str_op(joined,==, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
"Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats");
tor_free(joined);
@@ -516,18 +538,19 @@ test_container_smartlist_ints_eq(void *arg)
/** Run unit tests for bitarray code */
static void
-test_container_bitarray(void)
+test_container_bitarray(void *arg)
{
bitarray_t *ba = NULL;
int i, j, ok=1;
+ (void)arg;
ba = bitarray_init_zero(1);
- test_assert(ba);
- test_assert(! bitarray_is_set(ba, 0));
+ tt_assert(ba);
+ tt_assert(! bitarray_is_set(ba, 0));
bitarray_set(ba, 0);
- test_assert(bitarray_is_set(ba, 0));
+ tt_assert(bitarray_is_set(ba, 0));
bitarray_clear(ba, 0);
- test_assert(! bitarray_is_set(ba, 0));
+ tt_assert(! bitarray_is_set(ba, 0));
bitarray_free(ba);
ba = bitarray_init_zero(1023);
@@ -542,7 +565,7 @@ test_container_bitarray(void)
if (!bool_eq(bitarray_is_set(ba, j), j%i))
ok = 0;
}
- test_assert(ok);
+ tt_assert(ok);
if (i < 7)
++i;
else if (i == 28)
@@ -559,7 +582,7 @@ test_container_bitarray(void)
/** Run unit tests for digest set code (implemented as a hashtable or as a
* bloom filter) */
static void
-test_container_digestset(void)
+test_container_digestset(void *arg)
{
smartlist_t *included = smartlist_new();
char d[DIGEST_LEN];
@@ -568,6 +591,7 @@ test_container_digestset(void)
int false_positives = 0;
digestset_t *set = NULL;
+ (void)arg;
for (i = 0; i < 1000; ++i) {
crypto_rand(d, DIGEST_LEN);
smartlist_add(included, tor_memdup(d, DIGEST_LEN));
@@ -576,19 +600,19 @@ test_container_digestset(void)
SMARTLIST_FOREACH(included, const char *, cp,
if (digestset_contains(set, cp))
ok = 0);
- test_assert(ok);
+ tt_assert(ok);
SMARTLIST_FOREACH(included, const char *, cp,
digestset_add(set, cp));
SMARTLIST_FOREACH(included, const char *, cp,
if (!digestset_contains(set, cp))
ok = 0);
- test_assert(ok);
+ tt_assert(ok);
for (i = 0; i < 1000; ++i) {
crypto_rand(d, DIGEST_LEN);
if (digestset_contains(set, d))
++false_positives;
}
- test_assert(false_positives < 50); /* Should be far lower. */
+ tt_int_op(50, >, false_positives); /* Should be far lower. */
done:
if (set)
@@ -612,7 +636,7 @@ compare_strings_for_pqueue_(const void *p1, const void *p2)
/** Run unit tests for heap-based priority queue functions. */
static void
-test_container_pqueue(void)
+test_container_pqueue(void *arg)
{
smartlist_t *sl = smartlist_new();
int (*cmp)(const void *, const void*);
@@ -634,6 +658,8 @@ test_container_pqueue(void)
#define OK() smartlist_pqueue_assert_ok(sl, cmp, offset)
+ (void)arg;
+
cmp = compare_strings_for_pqueue_;
smartlist_pqueue_add(sl, cmp, offset, &cows);
smartlist_pqueue_add(sl, cmp, offset, &zebras);
@@ -649,31 +675,31 @@ test_container_pqueue(void)
OK();
- test_eq(smartlist_len(sl), 11);
- test_eq_ptr(smartlist_get(sl, 0), &apples);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &apples);
- test_eq(smartlist_len(sl), 10);
+ tt_int_op(smartlist_len(sl),==, 11);
+ tt_ptr_op(smartlist_get(sl, 0),==, &apples);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &apples);
+ tt_int_op(smartlist_len(sl),==, 10);
OK();
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &cows);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &daschunds);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &cows);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &daschunds);
smartlist_pqueue_add(sl, cmp, offset, &chinchillas);
OK();
smartlist_pqueue_add(sl, cmp, offset, &fireflies);
OK();
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &chinchillas);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &eggplants);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fireflies);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &chinchillas);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &eggplants);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fireflies);
OK();
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fish);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &frogs);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &lobsters);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &roquefort);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fish);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &frogs);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &lobsters);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &roquefort);
OK();
- test_eq(smartlist_len(sl), 3);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &squid);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &weissbier);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &zebras);
- test_eq(smartlist_len(sl), 0);
+ tt_int_op(smartlist_len(sl),==, 3);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &squid);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &weissbier);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &zebras);
+ tt_int_op(smartlist_len(sl),==, 0);
OK();
/* Now test remove. */
@@ -683,21 +709,21 @@ test_container_pqueue(void)
smartlist_pqueue_add(sl, cmp, offset, &apples);
smartlist_pqueue_add(sl, cmp, offset, &squid);
smartlist_pqueue_add(sl, cmp, offset, &zebras);
- test_eq(smartlist_len(sl), 6);
+ tt_int_op(smartlist_len(sl),==, 6);
OK();
smartlist_pqueue_remove(sl, cmp, offset, &zebras);
- test_eq(smartlist_len(sl), 5);
+ tt_int_op(smartlist_len(sl),==, 5);
OK();
smartlist_pqueue_remove(sl, cmp, offset, &cows);
- test_eq(smartlist_len(sl), 4);
+ tt_int_op(smartlist_len(sl),==, 4);
OK();
smartlist_pqueue_remove(sl, cmp, offset, &apples);
- test_eq(smartlist_len(sl), 3);
+ tt_int_op(smartlist_len(sl),==, 3);
OK();
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fish);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &frogs);
- test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &squid);
- test_eq(smartlist_len(sl), 0);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fish);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &frogs);
+ tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &squid);
+ tt_int_op(smartlist_len(sl),==, 0);
OK();
#undef OK
@@ -709,7 +735,7 @@ test_container_pqueue(void)
/** Run unit tests for string-to-void* map functions */
static void
-test_container_strmap(void)
+test_container_strmap(void *arg)
{
strmap_t *map;
strmap_iter_t *iter;
@@ -717,36 +743,45 @@ test_container_strmap(void)
void *v;
char *visited = NULL;
smartlist_t *found_keys = NULL;
+ char *v1 = tor_strdup("v1");
+ char *v99 = tor_strdup("v99");
+ char *v100 = tor_strdup("v100");
+ char *v101 = tor_strdup("v101");
+ char *v102 = tor_strdup("v102");
+ char *v103 = tor_strdup("v103");
+ char *v104 = tor_strdup("v104");
+ char *v105 = tor_strdup("v105");
+ (void)arg;
map = strmap_new();
- test_assert(map);
- test_eq(strmap_size(map), 0);
- test_assert(strmap_isempty(map));
- v = strmap_set(map, "K1", (void*)99);
- test_eq_ptr(v, NULL);
- test_assert(!strmap_isempty(map));
- v = strmap_set(map, "K2", (void*)101);
- test_eq_ptr(v, NULL);
- v = strmap_set(map, "K1", (void*)100);
- test_eq_ptr(v, (void*)99);
- test_eq_ptr(strmap_get(map,"K1"), (void*)100);
- test_eq_ptr(strmap_get(map,"K2"), (void*)101);
- test_eq_ptr(strmap_get(map,"K-not-there"), NULL);
+ tt_assert(map);
+ tt_int_op(strmap_size(map),==, 0);
+ tt_assert(strmap_isempty(map));
+ v = strmap_set(map, "K1", v99);
+ tt_ptr_op(v,==, NULL);
+ tt_assert(!strmap_isempty(map));
+ v = strmap_set(map, "K2", v101);
+ tt_ptr_op(v,==, NULL);
+ v = strmap_set(map, "K1", v100);
+ tt_ptr_op(v,==, v99);
+ tt_ptr_op(strmap_get(map,"K1"),==, v100);
+ tt_ptr_op(strmap_get(map,"K2"),==, v101);
+ tt_ptr_op(strmap_get(map,"K-not-there"),==, NULL);
strmap_assert_ok(map);
v = strmap_remove(map,"K2");
strmap_assert_ok(map);
- test_eq_ptr(v, (void*)101);
- test_eq_ptr(strmap_get(map,"K2"), NULL);
- test_eq_ptr(strmap_remove(map,"K2"), NULL);
-
- strmap_set(map, "K2", (void*)101);
- strmap_set(map, "K3", (void*)102);
- strmap_set(map, "K4", (void*)103);
- test_eq(strmap_size(map), 4);
+ tt_ptr_op(v,==, v101);
+ tt_ptr_op(strmap_get(map,"K2"),==, NULL);
+ tt_ptr_op(strmap_remove(map,"K2"),==, NULL);
+
+ strmap_set(map, "K2", v101);
+ strmap_set(map, "K3", v102);
+ strmap_set(map, "K4", v103);
+ tt_int_op(strmap_size(map),==, 4);
strmap_assert_ok(map);
- strmap_set(map, "K5", (void*)104);
- strmap_set(map, "K6", (void*)105);
+ strmap_set(map, "K5", v104);
+ strmap_set(map, "K6", v105);
strmap_assert_ok(map);
/* Test iterator. */
@@ -755,7 +790,7 @@ test_container_strmap(void)
while (!strmap_iter_done(iter)) {
strmap_iter_get(iter,&k,&v);
smartlist_add(found_keys, tor_strdup(k));
- test_eq_ptr(v, strmap_get(map, k));
+ tt_ptr_op(v,==, strmap_get(map, k));
if (!strcmp(k, "K2")) {
iter = strmap_iter_next_rmv(map,iter);
@@ -765,12 +800,12 @@ test_container_strmap(void)
}
/* Make sure we removed K2, but not the others. */
- test_eq_ptr(strmap_get(map, "K2"), NULL);
- test_eq_ptr(strmap_get(map, "K5"), (void*)104);
+ tt_ptr_op(strmap_get(map, "K2"),==, NULL);
+ tt_ptr_op(strmap_get(map, "K5"),==, v104);
/* Make sure we visited everyone once */
smartlist_sort_strings(found_keys);
visited = smartlist_join_strings(found_keys, ":", 0, NULL);
- test_streq(visited, "K1:K2:K3:K4:K5:K6");
+ tt_str_op(visited,==, "K1:K2:K3:K4:K5:K6");
strmap_assert_ok(map);
/* Clean up after ourselves. */
@@ -779,14 +814,14 @@ test_container_strmap(void)
/* Now try some lc functions. */
map = strmap_new();
- strmap_set_lc(map,"Ab.C", (void*)1);
- test_eq_ptr(strmap_get(map,"ab.c"), (void*)1);
+ strmap_set_lc(map,"Ab.C", v1);
+ tt_ptr_op(strmap_get(map,"ab.c"),==, v1);
strmap_assert_ok(map);
- test_eq_ptr(strmap_get_lc(map,"AB.C"), (void*)1);
- test_eq_ptr(strmap_get(map,"AB.C"), NULL);
- test_eq_ptr(strmap_remove_lc(map,"aB.C"), (void*)1);
+ tt_ptr_op(strmap_get_lc(map,"AB.C"),==, v1);
+ tt_ptr_op(strmap_get(map,"AB.C"),==, NULL);
+ tt_ptr_op(strmap_remove_lc(map,"aB.C"),==, v1);
strmap_assert_ok(map);
- test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL);
+ tt_ptr_op(strmap_get_lc(map,"AB.C"),==, NULL);
done:
if (map)
@@ -796,34 +831,66 @@ test_container_strmap(void)
smartlist_free(found_keys);
}
tor_free(visited);
+ tor_free(v1);
+ tor_free(v99);
+ tor_free(v100);
+ tor_free(v101);
+ tor_free(v102);
+ tor_free(v103);
+ tor_free(v104);
+ tor_free(v105);
}
/** Run unit tests for getting the median of a list. */
static void
-test_container_order_functions(void)
+test_container_order_functions(void *arg)
{
int lst[25], n = 0;
+ unsigned int lst2[25];
// int a=12,b=24,c=25,d=60,e=77;
#define median() median_int(lst, n)
+ (void)arg;
lst[n++] = 12;
- test_eq(12, median()); /* 12 */
+ tt_int_op(12,==, median()); /* 12 */
lst[n++] = 77;
//smartlist_shuffle(sl);
- test_eq(12, median()); /* 12, 77 */
+ tt_int_op(12,==, median()); /* 12, 77 */
lst[n++] = 77;
//smartlist_shuffle(sl);
- test_eq(77, median()); /* 12, 77, 77 */
+ tt_int_op(77,==, median()); /* 12, 77, 77 */
lst[n++] = 24;
- test_eq(24, median()); /* 12,24,77,77 */
+ tt_int_op(24,==, median()); /* 12,24,77,77 */
lst[n++] = 60;
lst[n++] = 12;
lst[n++] = 25;
//smartlist_shuffle(sl);
- test_eq(25, median()); /* 12,12,24,25,60,77,77 */
+ tt_int_op(25,==, median()); /* 12,12,24,25,60,77,77 */
#undef median
+#define third_quartile() third_quartile_uint32(lst2, n)
+
+ n = 0;
+ lst2[n++] = 1;
+ tt_int_op(1,==, third_quartile()); /* ~1~ */
+ lst2[n++] = 2;
+ tt_int_op(2,==, third_quartile()); /* 1, ~2~ */
+ lst2[n++] = 3;
+ lst2[n++] = 4;
+ lst2[n++] = 5;
+ tt_int_op(4,==, third_quartile()); /* 1, 2, 3, ~4~, 5 */
+ lst2[n++] = 6;
+ lst2[n++] = 7;
+ lst2[n++] = 8;
+ lst2[n++] = 9;
+ tt_int_op(7,==, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */
+ lst2[n++] = 10;
+ lst2[n++] = 11;
+ tt_int_op(9,==, third_quartile()); /* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */
+
+#undef third_quartile
+
done:
;
}
@@ -874,18 +941,26 @@ test_container_di_map(void *arg)
/** Run unit tests for fp_pair-to-void* map functions */
static void
-test_container_fp_pair_map(void)
+test_container_fp_pair_map(void *arg)
{
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;
+ char *v99 = tor_strdup("99");
+ char *v100 = tor_strdup("v100");
+ char *v101 = tor_strdup("v101");
+ char *v102 = tor_strdup("v102");
+ char *v103 = tor_strdup("v103");
+ char *v104 = tor_strdup("v104");
+ char *v105 = tor_strdup("v105");
+ (void)arg;
map = fp_pair_map_new();
- test_assert(map);
- test_eq(fp_pair_map_size(map), 0);
- test_assert(fp_pair_map_isempty(map));
+ tt_assert(map);
+ tt_int_op(fp_pair_map_size(map),==, 0);
+ tt_assert(fp_pair_map_isempty(map));
memset(fp1.first, 0x11, DIGEST_LEN);
memset(fp1.second, 0x12, DIGEST_LEN);
@@ -900,38 +975,38 @@ test_container_fp_pair_map(void)
memset(fp6.first, 0x61, DIGEST_LEN);
memset(fp6.second, 0x62, DIGEST_LEN);
- v = fp_pair_map_set(map, &fp1, (void*)99);
+ v = fp_pair_map_set(map, &fp1, v99);
tt_ptr_op(v, ==, NULL);
- test_assert(!fp_pair_map_isempty(map));
- v = fp_pair_map_set(map, &fp2, (void*)101);
+ tt_assert(!fp_pair_map_isempty(map));
+ v = fp_pair_map_set(map, &fp2, v101);
tt_ptr_op(v, ==, NULL);
- v = fp_pair_map_set(map, &fp1, (void*)100);
- tt_ptr_op(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);
+ v = fp_pair_map_set(map, &fp1, v100);
+ tt_ptr_op(v, ==, v99);
+ tt_ptr_op(fp_pair_map_get(map, &fp1),==, v100);
+ tt_ptr_op(fp_pair_map_get(map, &fp2),==, v101);
+ tt_ptr_op(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);
+ tt_ptr_op(v,==, v101);
+ tt_ptr_op(fp_pair_map_get(map, &fp2),==, NULL);
+ tt_ptr_op(fp_pair_map_remove(map, &fp2),==, NULL);
+
+ fp_pair_map_set(map, &fp2, v101);
+ fp_pair_map_set(map, &fp3, v102);
+ fp_pair_map_set(map, &fp4, v103);
+ tt_int_op(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_set(map, &fp5, v104);
+ fp_pair_map_set(map, &fp6, v105);
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));
+ tt_ptr_op(v,==, fp_pair_map_get(map, &k));
if (tor_memeq(&fp2, &k, sizeof(fp2))) {
iter = fp_pair_map_iter_next_rmv(map, iter);
@@ -941,8 +1016,8 @@ test_container_fp_pair_map(void)
}
/* 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);
+ tt_ptr_op(fp_pair_map_get(map, &fp2),==, NULL);
+ tt_ptr_op(fp_pair_map_get(map, &fp5),==, v104);
fp_pair_map_assert_ok(map);
/* Clean up after ourselves. */
@@ -952,10 +1027,17 @@ test_container_fp_pair_map(void)
done:
if (map)
fp_pair_map_free(map, NULL);
+ tor_free(v99);
+ tor_free(v100);
+ tor_free(v101);
+ tor_free(v102);
+ tor_free(v103);
+ tor_free(v104);
+ tor_free(v105);
}
#define CONTAINER_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_container_ ## name }
+ { #name, test_container_ ## name , 0, NULL, NULL }
#define CONTAINER(name, flags) \
{ #name, test_container_ ## name, (flags), NULL, NULL }
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 5d8edb6550..795c603fd4 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -5,6 +5,7 @@
#include "orconfig.h"
#define CRYPTO_CURVE25519_PRIVATE
+#define CRYPTO_S2K_PRIVATE
#include "or.h"
#include "test.h"
#include "aes.h"
@@ -13,6 +14,10 @@
#ifdef CURVE25519_ENABLED
#include "crypto_curve25519.h"
#endif
+#include "crypto_ed25519.h"
+#include "ed25519_vectors.inc"
+#include "crypto_s2k.h"
+#include "crypto_pwbox.h"
extern const char AUTHORITY_SIGNKEY_3[];
extern const char AUTHORITY_SIGNKEY_A_DIGEST[];
@@ -20,7 +25,7 @@ extern const char AUTHORITY_SIGNKEY_A_DIGEST256[];
/** Run unit tests for Diffie-Hellman functionality. */
static void
-test_crypto_dh(void)
+test_crypto_dh(void *arg)
{
crypto_dh_t *dh1 = crypto_dh_new(DH_TYPE_CIRCUIT);
crypto_dh_t *dh2 = crypto_dh_new(DH_TYPE_CIRCUIT);
@@ -30,24 +35,25 @@ test_crypto_dh(void)
char s2[DH_BYTES];
ssize_t s1len, s2len;
- test_eq(crypto_dh_get_bytes(dh1), DH_BYTES);
- test_eq(crypto_dh_get_bytes(dh2), DH_BYTES);
+ (void)arg;
+ tt_int_op(crypto_dh_get_bytes(dh1),==, DH_BYTES);
+ tt_int_op(crypto_dh_get_bytes(dh2),==, DH_BYTES);
memset(p1, 0, DH_BYTES);
memset(p2, 0, DH_BYTES);
- test_memeq(p1, p2, DH_BYTES);
- test_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
- test_memneq(p1, p2, DH_BYTES);
- test_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
- test_memneq(p1, p2, DH_BYTES);
+ tt_mem_op(p1,==, p2, DH_BYTES);
+ tt_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
+ tt_mem_op(p1,!=, p2, DH_BYTES);
+ tt_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
+ tt_mem_op(p1,!=, p2, DH_BYTES);
memset(s1, 0, DH_BYTES);
memset(s2, 0xFF, DH_BYTES);
s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p2, DH_BYTES, s1, 50);
s2len = crypto_dh_compute_secret(LOG_WARN, dh2, p1, DH_BYTES, s2, 50);
- test_assert(s1len > 0);
- test_eq(s1len, s2len);
- test_memeq(s1, s2, s1len);
+ tt_assert(s1len > 0);
+ tt_int_op(s1len,==, s2len);
+ tt_mem_op(s1,==, s2, s1len);
{
/* XXXX Now fabricate some bad values and make sure they get caught,
@@ -63,17 +69,18 @@ test_crypto_dh(void)
/** Run unit tests for our random number generation function and its wrappers.
*/
static void
-test_crypto_rng(void)
+test_crypto_rng(void *arg)
{
int i, j, allok;
char data1[100], data2[100];
double d;
/* Try out RNG. */
- test_assert(! crypto_seed_rng(0));
+ (void)arg;
+ tt_assert(! crypto_seed_rng(0));
crypto_rand(data1, 100);
crypto_rand(data2, 100);
- test_memneq(data1,data2,100);
+ tt_mem_op(data1,!=, data2,100);
allok = 1;
for (i = 0; i < 100; ++i) {
uint64_t big;
@@ -88,8 +95,8 @@ test_crypto_rng(void)
if (big >= 5)
allok = 0;
d = crypto_rand_double();
- test_assert(d >= 0);
- test_assert(d < 1.0);
+ tt_assert(d >= 0);
+ tt_assert(d < 1.0);
host = crypto_random_hostname(3,8,"www.",".onion");
if (strcmpstart(host,"www.") ||
strcmpend(host,".onion") ||
@@ -98,7 +105,7 @@ test_crypto_rng(void)
allok = 0;
tor_free(host);
}
- test_assert(allok);
+ tt_assert(allok);
done:
;
}
@@ -128,15 +135,15 @@ test_crypto_aes(void *arg)
memset(data2, 0, 1024);
memset(data3, 0, 1024);
env1 = crypto_cipher_new(NULL);
- test_neq_ptr(env1, 0);
+ tt_ptr_op(env1, !=, NULL);
env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
- test_neq_ptr(env2, 0);
+ tt_ptr_op(env2, !=, NULL);
/* Try encrypting 512 chars. */
crypto_cipher_encrypt(env1, data2, data1, 512);
crypto_cipher_decrypt(env2, data3, data2, 512);
- test_memeq(data1, data3, 512);
- test_memneq(data1, data2, 512);
+ tt_mem_op(data1,==, data3, 512);
+ tt_mem_op(data1,!=, data2, 512);
/* Now encrypt 1 at a time, and get 1 at a time. */
for (j = 512; j < 560; ++j) {
@@ -145,7 +152,7 @@ test_crypto_aes(void *arg)
for (j = 512; j < 560; ++j) {
crypto_cipher_decrypt(env2, data3+j, data2+j, 1);
}
- test_memeq(data1, data3, 560);
+ tt_mem_op(data1,==, data3, 560);
/* Now encrypt 3 at a time, and get 5 at a time. */
for (j = 560; j < 1024-5; j += 3) {
crypto_cipher_encrypt(env1, data2+j, data1+j, 3);
@@ -153,7 +160,7 @@ test_crypto_aes(void *arg)
for (j = 560; j < 1024-5; j += 5) {
crypto_cipher_decrypt(env2, data3+j, data2+j, 5);
}
- test_memeq(data1, data3, 1024-5);
+ tt_mem_op(data1,==, data3, 1024-5);
/* Now make sure that when we encrypt with different chunk sizes, we get
the same results. */
crypto_cipher_free(env2);
@@ -161,7 +168,7 @@ test_crypto_aes(void *arg)
memset(data3, 0, 1024);
env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
- test_neq_ptr(env2, NULL);
+ tt_ptr_op(env2, !=, NULL);
for (j = 0; j < 1024-16; j += 17) {
crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
}
@@ -170,7 +177,7 @@ test_crypto_aes(void *arg)
printf("%d: %d\t%d\n", j, (int) data2[j], (int) data3[j]);
}
}
- test_memeq(data2, data3, 1024-16);
+ tt_mem_op(data2,==, data3, 1024-16);
crypto_cipher_free(env1);
env1 = NULL;
crypto_cipher_free(env2);
@@ -237,7 +244,7 @@ test_crypto_aes(void *arg)
"\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff");
crypto_cipher_crypt_inplace(env1, data2, 64);
- test_assert(tor_mem_is_zero(data2, 64));
+ tt_assert(tor_mem_is_zero(data2, 64));
done:
tor_free(mem_op_hex_tmp);
@@ -252,7 +259,7 @@ test_crypto_aes(void *arg)
/** Run unit tests for our SHA-1 functionality */
static void
-test_crypto_sha(void)
+test_crypto_sha(void *arg)
{
crypto_digest_t *d1 = NULL, *d2 = NULL;
int i;
@@ -263,6 +270,7 @@ test_crypto_sha(void)
char *mem_op_hex_tmp=NULL;
/* Test SHA-1 with a test vector from the specification. */
+ (void)arg;
i = crypto_digest(data, "abc", 3);
test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D");
tt_int_op(i, ==, 0);
@@ -277,13 +285,13 @@ test_crypto_sha(void)
/* Case empty (wikipedia) */
crypto_hmac_sha256(digest, "", 0, "", 0);
- test_streq(hex_str(digest, 32),
+ tt_str_op(hex_str(digest, 32),==,
"B613679A0814D9EC772F95D778C35FC5FF1697C493715653C6C712144292C5AD");
/* Case quick-brown (wikipedia) */
crypto_hmac_sha256(digest, "key", 3,
"The quick brown fox jumps over the lazy dog", 43);
- test_streq(hex_str(digest, 32),
+ tt_str_op(hex_str(digest, 32),==,
"F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8");
/* "Test Case 1" from RFC 4231 */
@@ -344,43 +352,43 @@ test_crypto_sha(void)
/* Incremental digest code. */
d1 = crypto_digest_new();
- test_assert(d1);
+ tt_assert(d1);
crypto_digest_add_bytes(d1, "abcdef", 6);
d2 = crypto_digest_dup(d1);
- test_assert(d2);
+ tt_assert(d2);
crypto_digest_add_bytes(d2, "ghijkl", 6);
crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
crypto_digest(d_out2, "abcdefghijkl", 12);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
+ tt_mem_op(d_out1,==, d_out2, DIGEST_LEN);
crypto_digest_assign(d2, d1);
crypto_digest_add_bytes(d2, "mno", 3);
crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
crypto_digest(d_out2, "abcdefmno", 9);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
+ tt_mem_op(d_out1,==, d_out2, DIGEST_LEN);
crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
crypto_digest(d_out2, "abcdef", 6);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
+ tt_mem_op(d_out1,==, d_out2, DIGEST_LEN);
crypto_digest_free(d1);
crypto_digest_free(d2);
/* Incremental digest code with sha256 */
d1 = crypto_digest256_new(DIGEST_SHA256);
- test_assert(d1);
+ tt_assert(d1);
crypto_digest_add_bytes(d1, "abcdef", 6);
d2 = crypto_digest_dup(d1);
- test_assert(d2);
+ tt_assert(d2);
crypto_digest_add_bytes(d2, "ghijkl", 6);
crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
crypto_digest256(d_out2, "abcdefghijkl", 12, DIGEST_SHA256);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
+ tt_mem_op(d_out1,==, d_out2, DIGEST_LEN);
crypto_digest_assign(d2, d1);
crypto_digest_add_bytes(d2, "mno", 3);
crypto_digest_get_digest(d2, d_out1, sizeof(d_out1));
crypto_digest256(d_out2, "abcdefmno", 9, DIGEST_SHA256);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
+ tt_mem_op(d_out1,==, d_out2, DIGEST_LEN);
crypto_digest_get_digest(d1, d_out1, sizeof(d_out1));
crypto_digest256(d_out2, "abcdef", 6, DIGEST_SHA256);
- test_memeq(d_out1, d_out2, DIGEST_LEN);
+ tt_mem_op(d_out1,==, d_out2, DIGEST_LEN);
done:
if (d1)
@@ -392,7 +400,7 @@ test_crypto_sha(void)
/** Run unit tests for our public key crypto functions */
static void
-test_crypto_pk(void)
+test_crypto_pk(void *arg)
{
crypto_pk_t *pk1 = NULL, *pk2 = NULL;
char *encoded = NULL;
@@ -401,74 +409,83 @@ test_crypto_pk(void)
int i, len;
/* Public-key ciphers */
+ (void)arg;
pk1 = pk_generate(0);
pk2 = crypto_pk_new();
- test_assert(pk1 && pk2);
- test_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size));
- test_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size));
- test_eq(0, crypto_pk_cmp_keys(pk1, pk2));
+ tt_assert(pk1 && pk2);
+ tt_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size));
+ tt_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size));
+ tt_int_op(0,==, crypto_pk_cmp_keys(pk1, pk2));
/* comparison between keys and NULL */
tt_int_op(crypto_pk_cmp_keys(NULL, pk1), <, 0);
tt_int_op(crypto_pk_cmp_keys(NULL, NULL), ==, 0);
tt_int_op(crypto_pk_cmp_keys(pk1, NULL), >, 0);
- test_eq(128, crypto_pk_keysize(pk1));
- test_eq(1024, crypto_pk_num_bits(pk1));
- test_eq(128, crypto_pk_keysize(pk2));
- test_eq(1024, crypto_pk_num_bits(pk2));
+ tt_int_op(128,==, crypto_pk_keysize(pk1));
+ tt_int_op(1024,==, crypto_pk_num_bits(pk1));
+ tt_int_op(128,==, crypto_pk_keysize(pk2));
+ tt_int_op(1024,==, crypto_pk_num_bits(pk2));
- test_eq(128, crypto_pk_public_encrypt(pk2, data1, sizeof(data1),
+ tt_int_op(128,==, crypto_pk_public_encrypt(pk2, data1, sizeof(data1),
"Hello whirled.", 15,
PK_PKCS1_OAEP_PADDING));
- test_eq(128, crypto_pk_public_encrypt(pk1, data2, sizeof(data1),
+ tt_int_op(128,==, crypto_pk_public_encrypt(pk1, data2, sizeof(data1),
"Hello whirled.", 15,
PK_PKCS1_OAEP_PADDING));
/* oaep padding should make encryption not match */
- test_memneq(data1, data2, 128);
- test_eq(15, crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data1, 128,
+ tt_mem_op(data1,!=, data2, 128);
+ tt_int_op(15,==,
+ crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data1, 128,
PK_PKCS1_OAEP_PADDING,1));
- test_streq(data3, "Hello whirled.");
+ tt_str_op(data3,==, "Hello whirled.");
memset(data3, 0, 1024);
- test_eq(15, crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128,
+ tt_int_op(15,==,
+ crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128,
PK_PKCS1_OAEP_PADDING,1));
- test_streq(data3, "Hello whirled.");
+ tt_str_op(data3,==, "Hello whirled.");
/* Can't decrypt with public key. */
- test_eq(-1, crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data2, 128,
+ tt_int_op(-1,==,
+ crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data2, 128,
PK_PKCS1_OAEP_PADDING,1));
/* Try again with bad padding */
memcpy(data2+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */
- test_eq(-1, crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128,
+ tt_int_op(-1,==,
+ crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128,
PK_PKCS1_OAEP_PADDING,1));
/* File operations: save and load private key */
- test_assert(! crypto_pk_write_private_key_to_filename(pk1,
+ tt_assert(! crypto_pk_write_private_key_to_filename(pk1,
get_fname("pkey1")));
/* failing case for read: can't read. */
- test_assert(crypto_pk_read_private_key_from_filename(pk2,
+ tt_assert(crypto_pk_read_private_key_from_filename(pk2,
get_fname("xyzzy")) < 0);
write_str_to_file(get_fname("xyzzy"), "foobar", 6);
/* Failing case for read: no key. */
- test_assert(crypto_pk_read_private_key_from_filename(pk2,
+ tt_assert(crypto_pk_read_private_key_from_filename(pk2,
get_fname("xyzzy")) < 0);
- test_assert(! crypto_pk_read_private_key_from_filename(pk2,
+ tt_assert(! crypto_pk_read_private_key_from_filename(pk2,
get_fname("pkey1")));
- test_eq(15, crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data1, 128,
+ tt_int_op(15,==,
+ crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data1, 128,
PK_PKCS1_OAEP_PADDING,1));
/* Now try signing. */
strlcpy(data1, "Ossifrage", 1024);
- test_eq(128, crypto_pk_private_sign(pk1, data2, sizeof(data2), data1, 10));
- test_eq(10,
+ tt_int_op(128,==,
+ crypto_pk_private_sign(pk1, data2, sizeof(data2), data1, 10));
+ tt_int_op(10,==,
crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128));
- test_streq(data3, "Ossifrage");
+ tt_str_op(data3,==, "Ossifrage");
/* Try signing digests. */
- test_eq(128, crypto_pk_private_sign_digest(pk1, data2, sizeof(data2),
+ tt_int_op(128,==, crypto_pk_private_sign_digest(pk1, data2, sizeof(data2),
data1, 10));
- test_eq(20,
+ tt_int_op(20,==,
crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128));
- test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
- test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));
+ tt_int_op(0,==,
+ crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
+ tt_int_op(-1,==,
+ crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));
/*XXXX test failed signing*/
@@ -476,9 +493,9 @@ test_crypto_pk(void)
crypto_pk_free(pk2);
pk2 = NULL;
i = crypto_pk_asn1_encode(pk1, data1, 1024);
- test_assert(i>0);
+ tt_int_op(i, >, 0);
pk2 = crypto_pk_asn1_decode(data1, i);
- test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
+ tt_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
/* Try with hybrid encryption wrappers. */
crypto_rand(data1, 1024);
@@ -487,19 +504,19 @@ test_crypto_pk(void)
memset(data3,0,1024);
len = crypto_pk_public_hybrid_encrypt(pk1,data2,sizeof(data2),
data1,i,PK_PKCS1_OAEP_PADDING,0);
- test_assert(len>=0);
+ tt_int_op(len, >=, 0);
len = crypto_pk_private_hybrid_decrypt(pk1,data3,sizeof(data3),
data2,len,PK_PKCS1_OAEP_PADDING,1);
- test_eq(len,i);
- test_memeq(data1,data3,i);
+ tt_int_op(len,==, i);
+ tt_mem_op(data1,==, data3,i);
}
/* Try copy_full */
crypto_pk_free(pk2);
pk2 = crypto_pk_copy_full(pk1);
- test_assert(pk2 != NULL);
- test_neq_ptr(pk1, pk2);
- test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
+ tt_assert(pk2 != NULL);
+ tt_ptr_op(pk1, !=, pk2);
+ tt_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
done:
if (pk1)
@@ -532,7 +549,7 @@ test_crypto_pk_fingerprints(void *arg)
/* Is digest as expected? */
crypto_digest(d, encoded, n);
tt_int_op(0, ==, crypto_pk_get_digest(pk, d2));
- test_memeq(d, d2, DIGEST_LEN);
+ tt_mem_op(d,==, d2, DIGEST_LEN);
/* Is fingerprint right? */
tt_int_op(0, ==, crypto_pk_get_fingerprint(pk, fingerprint, 0));
@@ -561,28 +578,29 @@ test_crypto_pk_fingerprints(void *arg)
/** Sanity check for crypto pk digests */
static void
-test_crypto_digests(void)
+test_crypto_digests(void *arg)
{
crypto_pk_t *k = NULL;
ssize_t r;
digests_t pkey_digests;
char digest[DIGEST_LEN];
+ (void)arg;
k = crypto_pk_new();
- test_assert(k);
+ tt_assert(k);
r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3, -1);
- test_assert(!r);
+ tt_assert(!r);
r = crypto_pk_get_digest(k, digest);
- test_assert(r == 0);
- test_memeq(hex_str(digest, DIGEST_LEN),
+ tt_assert(r == 0);
+ tt_mem_op(hex_str(digest, DIGEST_LEN),==,
AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN);
r = crypto_pk_get_all_digests(k, &pkey_digests);
- test_memeq(hex_str(pkey_digests.d[DIGEST_SHA1], DIGEST_LEN),
+ tt_mem_op(hex_str(pkey_digests.d[DIGEST_SHA1], DIGEST_LEN),==,
AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN);
- test_memeq(hex_str(pkey_digests.d[DIGEST_SHA256], DIGEST256_LEN),
+ tt_mem_op(hex_str(pkey_digests.d[DIGEST_SHA256], DIGEST256_LEN),==,
AUTHORITY_SIGNKEY_A_DIGEST256, HEX_DIGEST256_LEN);
done:
crypto_pk_free(k);
@@ -591,58 +609,59 @@ test_crypto_digests(void)
/** Run unit tests for misc crypto formatting functionality (base64, base32,
* fingerprints, etc) */
static void
-test_crypto_formats(void)
+test_crypto_formats(void *arg)
{
char *data1 = NULL, *data2 = NULL, *data3 = NULL;
int i, j, idx;
+ (void)arg;
data1 = tor_malloc(1024);
data2 = tor_malloc(1024);
data3 = tor_malloc(1024);
- test_assert(data1 && data2 && data3);
+ tt_assert(data1 && data2 && data3);
/* Base64 tests */
memset(data1, 6, 1024);
for (idx = 0; idx < 10; ++idx) {
i = base64_encode(data2, 1024, data1, idx);
- test_assert(i >= 0);
+ tt_int_op(i, >=, 0);
j = base64_decode(data3, 1024, data2, i);
- test_eq(j,idx);
- test_memeq(data3, data1, idx);
+ tt_int_op(j,==, idx);
+ tt_mem_op(data3,==, data1, idx);
}
strlcpy(data1, "Test string that contains 35 chars.", 1024);
strlcat(data1, " 2nd string that contains 35 chars.", 1024);
i = base64_encode(data2, 1024, data1, 71);
- test_assert(i >= 0);
+ tt_int_op(i, >=, 0);
j = base64_decode(data3, 1024, data2, i);
- test_eq(j, 71);
- test_streq(data3, data1);
- test_assert(data2[i] == '\0');
+ tt_int_op(j,==, 71);
+ tt_str_op(data3,==, data1);
+ tt_int_op(data2[i], ==, '\0');
crypto_rand(data1, DIGEST_LEN);
memset(data2, 100, 1024);
digest_to_base64(data2, data1);
- test_eq(BASE64_DIGEST_LEN, strlen(data2));
- test_eq(100, data2[BASE64_DIGEST_LEN+2]);
+ tt_int_op(BASE64_DIGEST_LEN,==, strlen(data2));
+ tt_int_op(100,==, data2[BASE64_DIGEST_LEN+2]);
memset(data3, 99, 1024);
- test_eq(digest_from_base64(data3, data2), 0);
- test_memeq(data1, data3, DIGEST_LEN);
- test_eq(99, data3[DIGEST_LEN+1]);
+ tt_int_op(digest_from_base64(data3, data2),==, 0);
+ tt_mem_op(data1,==, data3, DIGEST_LEN);
+ tt_int_op(99,==, data3[DIGEST_LEN+1]);
- test_assert(digest_from_base64(data3, "###") < 0);
+ tt_assert(digest_from_base64(data3, "###") < 0);
/* Encoding SHA256 */
crypto_rand(data2, DIGEST256_LEN);
memset(data2, 100, 1024);
digest256_to_base64(data2, data1);
- test_eq(BASE64_DIGEST256_LEN, strlen(data2));
- test_eq(100, data2[BASE64_DIGEST256_LEN+2]);
+ tt_int_op(BASE64_DIGEST256_LEN,==, strlen(data2));
+ tt_int_op(100,==, data2[BASE64_DIGEST256_LEN+2]);
memset(data3, 99, 1024);
- test_eq(digest256_from_base64(data3, data2), 0);
- test_memeq(data1, data3, DIGEST256_LEN);
- test_eq(99, data3[DIGEST256_LEN+1]);
+ tt_int_op(digest256_from_base64(data3, data2),==, 0);
+ tt_mem_op(data1,==, data3, DIGEST256_LEN);
+ tt_int_op(99,==, data3[DIGEST256_LEN+1]);
/* Base32 tests */
strlcpy(data1, "5chrs", 1024);
@@ -651,27 +670,27 @@ test_crypto_formats(void)
* By 5s: [00110 10101 10001 10110 10000 11100 10011 10011]
*/
base32_encode(data2, 9, data1, 5);
- test_streq(data2, "gvrwq4tt");
+ tt_str_op(data2,==, "gvrwq4tt");
strlcpy(data1, "\xFF\xF5\x6D\x44\xAE\x0D\x5C\xC9\x62\xC4", 1024);
base32_encode(data2, 30, data1, 10);
- test_streq(data2, "772w2rfobvomsywe");
+ tt_str_op(data2,==, "772w2rfobvomsywe");
/* Base16 tests */
strlcpy(data1, "6chrs\xff", 1024);
base16_encode(data2, 13, data1, 6);
- test_streq(data2, "3663687273FF");
+ tt_str_op(data2,==, "3663687273FF");
strlcpy(data1, "f0d678affc000100", 1024);
i = base16_decode(data2, 8, data1, 16);
- test_eq(i,0);
- test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
+ tt_int_op(i,==, 0);
+ tt_mem_op(data2,==, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);
/* now try some failing base16 decodes */
- test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
- test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
+ tt_int_op(-1,==, base16_decode(data2, 8, data1, 15)); /* odd input len */
+ tt_int_op(-1,==, base16_decode(data2, 7, data1, 16)); /* dest too short */
strlcpy(data1, "f0dz!8affc000100", 1024);
- test_eq(-1, base16_decode(data2, 8, data1, 16));
+ tt_int_op(-1,==, base16_decode(data2, 8, data1, 16));
tor_free(data1);
tor_free(data2);
@@ -680,10 +699,10 @@ test_crypto_formats(void)
/* Add spaces to fingerprint */
{
data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000");
- test_eq(strlen(data1), 40);
+ tt_int_op(strlen(data1),==, 40);
data2 = tor_malloc(FINGERPRINT_LEN+1);
crypto_add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1);
- test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
+ tt_str_op(data2,==, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000");
tor_free(data1);
tor_free(data2);
}
@@ -696,37 +715,377 @@ test_crypto_formats(void)
/** Run unit tests for our secret-to-key passphrase hashing functionality. */
static void
-test_crypto_s2k(void)
+test_crypto_s2k_rfc2440(void *arg)
{
char buf[29];
char buf2[29];
char *buf3 = NULL;
int i;
+ (void)arg;
memset(buf, 0, sizeof(buf));
memset(buf2, 0, sizeof(buf2));
buf3 = tor_malloc(65536);
memset(buf3, 0, 65536);
- secret_to_key(buf+9, 20, "", 0, buf);
+ secret_to_key_rfc2440(buf+9, 20, "", 0, buf);
crypto_digest(buf2+9, buf3, 1024);
- test_memeq(buf, buf2, 29);
+ tt_mem_op(buf,==, buf2, 29);
memcpy(buf,"vrbacrda",8);
memcpy(buf2,"vrbacrda",8);
buf[8] = 96;
buf2[8] = 96;
- secret_to_key(buf+9, 20, "12345678", 8, buf);
+ secret_to_key_rfc2440(buf+9, 20, "12345678", 8, buf);
for (i = 0; i < 65536; i += 16) {
memcpy(buf3+i, "vrbacrda12345678", 16);
}
crypto_digest(buf2+9, buf3, 65536);
- test_memeq(buf, buf2, 29);
+ tt_mem_op(buf,==, buf2, 29);
done:
tor_free(buf3);
}
+static void
+run_s2k_tests(const unsigned flags, const unsigned type,
+ int speclen, const int keylen, int legacy)
+{
+ uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN];
+ int r;
+ size_t sz;
+ const char pw1[] = "You can't come in here unless you say swordfish!";
+ const char pw2[] = "Now, I give you one more guess.";
+
+ r = secret_to_key_new(buf, sizeof(buf), &sz,
+ pw1, strlen(pw1), flags);
+ tt_int_op(r, ==, S2K_OKAY);
+ tt_int_op(buf[0], ==, type);
+
+ tt_int_op(sz, ==, keylen + speclen);
+
+ if (legacy) {
+ memmove(buf, buf+1, sz-1);
+ --sz;
+ --speclen;
+ }
+
+ tt_int_op(S2K_OKAY, ==,
+ secret_to_key_check(buf, sz, pw1, strlen(pw1)));
+
+ tt_int_op(S2K_BAD_SECRET, ==,
+ secret_to_key_check(buf, sz, pw2, strlen(pw2)));
+
+ /* Move key to buf2, and clear it. */
+ memset(buf3, 0, sizeof(buf3));
+ memcpy(buf2, buf+speclen, keylen);
+ memset(buf+speclen, 0, sz - speclen);
+
+ /* Derivekey should produce the same results. */
+ tt_int_op(S2K_OKAY, ==,
+ secret_to_key_derivekey(buf3, keylen, buf, speclen, pw1, strlen(pw1)));
+
+ tt_mem_op(buf2, ==, buf3, keylen);
+
+ /* Derivekey with a longer output should fill the output. */
+ memset(buf2, 0, sizeof(buf2));
+ tt_int_op(S2K_OKAY, ==,
+ secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen,
+ pw1, strlen(pw1)));
+
+ tt_mem_op(buf2, !=, buf3, sizeof(buf2));
+
+ memset(buf3, 0, sizeof(buf3));
+ tt_int_op(S2K_OKAY, ==,
+ secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen,
+ pw1, strlen(pw1)));
+ tt_mem_op(buf2, ==, buf3, sizeof(buf3));
+ tt_assert(!tor_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen));
+
+ done:
+ ;
+}
+
+static void
+test_crypto_s2k_general(void *arg)
+{
+ const char *which = arg;
+
+ if (!strcmp(which, "scrypt")) {
+ run_s2k_tests(0, 2, 19, 32, 0);
+ } else if (!strcmp(which, "scrypt-low")) {
+ run_s2k_tests(S2K_FLAG_LOW_MEM, 2, 19, 32, 0);
+ } else if (!strcmp(which, "pbkdf2")) {
+ run_s2k_tests(S2K_FLAG_USE_PBKDF2, 1, 18, 20, 0);
+ } else if (!strcmp(which, "rfc2440")) {
+ run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 0);
+ } else if (!strcmp(which, "rfc2440-legacy")) {
+ run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 1);
+ } else {
+ tt_fail();
+ }
+}
+
+static void
+test_crypto_s2k_errors(void *arg)
+{
+ uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN];
+ size_t sz;
+
+ (void)arg;
+
+ /* Bogus specifiers: simple */
+ tt_int_op(S2K_BAD_LEN, ==,
+ secret_to_key_derivekey(buf, sizeof(buf),
+ (const uint8_t*)"", 0, "ABC", 3));
+ tt_int_op(S2K_BAD_ALGORITHM, ==,
+ secret_to_key_derivekey(buf, sizeof(buf),
+ (const uint8_t*)"\x10", 1, "ABC", 3));
+ tt_int_op(S2K_BAD_LEN, ==,
+ secret_to_key_derivekey(buf, sizeof(buf),
+ (const uint8_t*)"\x01\x02", 2, "ABC", 3));
+
+ tt_int_op(S2K_BAD_LEN, ==,
+ secret_to_key_check((const uint8_t*)"", 0, "ABC", 3));
+ tt_int_op(S2K_BAD_ALGORITHM, ==,
+ secret_to_key_check((const uint8_t*)"\x10", 1, "ABC", 3));
+ tt_int_op(S2K_BAD_LEN, ==,
+ secret_to_key_check((const uint8_t*)"\x01\x02", 2, "ABC", 3));
+
+ /* too long gets "BAD_LEN" too */
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 2;
+ tt_int_op(S2K_BAD_LEN, ==,
+ secret_to_key_derivekey(buf2, sizeof(buf2),
+ buf, sizeof(buf), "ABC", 3));
+
+ /* Truncated output */
+#ifdef HAVE_LIBSCRYPT_H
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 50, &sz,
+ "ABC", 3, 0));
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 50, &sz,
+ "ABC", 3, S2K_FLAG_LOW_MEM));
+#endif
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 37, &sz,
+ "ABC", 3, S2K_FLAG_USE_PBKDF2));
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 29, &sz,
+ "ABC", 3, S2K_FLAG_NO_SCRYPT));
+
+#ifdef HAVE_LIBSCRYPT_H
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 18, 0));
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 18,
+ S2K_FLAG_LOW_MEM));
+#endif
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 17,
+ S2K_FLAG_USE_PBKDF2));
+ tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 9,
+ S2K_FLAG_NO_SCRYPT));
+
+ /* Now try using type-specific bogus specifiers. */
+
+ /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow
+ * int32_t. */
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 1; /* pbkdf2 */
+ buf[17] = 100; /* 1<<100 is much bigger than INT32_MAX */
+ tt_int_op(S2K_BAD_PARAMS, ==,
+ secret_to_key_derivekey(buf2, sizeof(buf2),
+ buf, 18, "ABC", 3));
+
+#ifdef HAVE_LIBSCRYPT_H
+ /* It's a bad scrypt buffer if N would overflow uint64 */
+ memset(buf, 0, sizeof(buf));
+ buf[0] = 2; /* scrypt */
+ buf[17] = 100; /* 1<<100 is much bigger than UINT64_MAX */
+ tt_int_op(S2K_BAD_PARAMS, ==,
+ secret_to_key_derivekey(buf2, sizeof(buf2),
+ buf, 19, "ABC", 3));
+#endif
+
+ done:
+ ;
+}
+
+static void
+test_crypto_scrypt_vectors(void *arg)
+{
+ char *mem_op_hex_tmp = NULL;
+ uint8_t spec[64], out[64];
+
+ (void)arg;
+#ifndef HAVE_LIBSCRYPT_H
+ if (1)
+ tt_skip();
+#endif
+
+ /* Test vectors from
+ http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11.
+
+ Note that the names of 'r' and 'N' are switched in that section. Or
+ possibly in libscrypt.
+ */
+
+ base16_decode((char*)spec, sizeof(spec),
+ "0400", 4);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, ==,
+ secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2));
+ test_memeq_hex(out,
+ "77d6576238657b203b19ca42c18a0497"
+ "f16b4844e3074ae8dfdffa3fede21442"
+ "fcd0069ded0948f8326a753a0fc81f17"
+ "e8d3e0fb2e0d3628cf35e20c38d18906");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "4e61436c" "0A34", 12);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, ==,
+ secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2));
+ test_memeq_hex(out,
+ "fdbabe1c9d3472007856e7190d01e9fe"
+ "7c6ad7cbc8237830e77376634b373162"
+ "2eaf30d92e22a3886ff109279d9830da"
+ "c727afb94a83ee6d8360cbdfa2cc0640");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "536f6469756d43686c6f72696465" "0e30", 32);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, ==,
+ secret_to_key_compute_key(out, 64, spec, 16,
+ "pleaseletmein", 13, 2));
+ test_memeq_hex(out,
+ "7023bdcb3afd7348461c06cd81fd38eb"
+ "fda8fbba904f8e3ea9b543f6545da1f2"
+ "d5432955613f0fcf62d49705242a9af9"
+ "e61e85dc0d651e40dfcf017b45575887");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "536f6469756d43686c6f72696465" "1430", 32);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(64, ==,
+ secret_to_key_compute_key(out, 64, spec, 16,
+ "pleaseletmein", 13, 2));
+ test_memeq_hex(out,
+ "2101cb9b6a511aaeaddbbe09cf70f881"
+ "ec568d574a2ffd4dabe5ee9820adaa47"
+ "8e56fd8f4ba5d09ffa1c6d927c40f4c3"
+ "37304049e8a952fbcbf45c6fa77a41a4");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_pbkdf2_vectors(void *arg)
+{
+ char *mem_op_hex_tmp = NULL;
+ uint8_t spec[64], out[64];
+ (void)arg;
+
+ /* Test vectors from RFC6070, section 2 */
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "00" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, ==,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "01" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, ==,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "0C" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, ==,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c74" "18" , 10);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(20, ==,
+ secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
+ test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "73616c7453414c5473616c7453414c5473616c745"
+ "3414c5473616c7453414c5473616c74" "0C" , 74);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(25, ==,
+ secret_to_key_compute_key(out, 25, spec, 37,
+ "passwordPASSWORDpassword", 24, 1));
+ test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");
+
+ base16_decode((char*)spec, sizeof(spec),
+ "7361006c74" "0c" , 12);
+ memset(out, 0x00, sizeof(out));
+ tt_int_op(16, ==,
+ secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1));
+ test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_pwbox(void *arg)
+{
+ uint8_t *boxed=NULL, *decoded=NULL;
+ size_t len, dlen;
+ unsigned i;
+ const char msg[] = "This bunny reminds you that you still have a "
+ "salamander in your sylladex. She is holding the bunny Dave got you. "
+ "It’s sort of uncanny how similar they are, aside from the knitted "
+ "enhancements. Seriously, what are the odds?? So weird.";
+ const char pw[] = "I'm a night owl and a wise bird too";
+
+ const unsigned flags[] = { 0,
+ S2K_FLAG_NO_SCRYPT,
+ S2K_FLAG_LOW_MEM,
+ S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM,
+ S2K_FLAG_USE_PBKDF2 };
+ (void)arg;
+
+ for (i = 0; i < ARRAY_LENGTH(flags); ++i) {
+ tt_int_op(0, ==, crypto_pwbox(&boxed, &len,
+ (const uint8_t*)msg, strlen(msg),
+ pw, strlen(pw), flags[i]));
+ tt_assert(boxed);
+ tt_assert(len > 128+32);
+
+ tt_int_op(0, ==, crypto_unpwbox(&decoded, &dlen, boxed, len,
+ pw, strlen(pw)));
+
+ tt_assert(decoded);
+ tt_uint_op(dlen, ==, strlen(msg));
+ tt_mem_op(decoded, ==, msg, dlen);
+
+ tor_free(decoded);
+
+ tt_int_op(UNPWBOX_BAD_SECRET, ==, crypto_unpwbox(&decoded, &dlen,
+ boxed, len,
+ pw, strlen(pw)-1));
+ boxed[len-1] ^= 1;
+ tt_int_op(UNPWBOX_BAD_SECRET, ==, crypto_unpwbox(&decoded, &dlen,
+ boxed, len,
+ pw, strlen(pw)));
+ boxed[0] = 255;
+ tt_int_op(UNPWBOX_CORRUPTED, ==, crypto_unpwbox(&decoded, &dlen,
+ boxed, len,
+ pw, strlen(pw)));
+
+ tor_free(boxed);
+ }
+
+ done:
+ tor_free(boxed);
+ tor_free(decoded);
+}
+
/** Test AES-CTR encryption and decryption with IV. */
static void
test_crypto_aes_iv(void *arg)
@@ -757,79 +1116,79 @@ test_crypto_aes_iv(void *arg)
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 4095,
plain, 4095);
- test_eq(encrypted_size, 16 + 4095);
+ tt_int_op(encrypted_size,==, 16 + 4095);
tt_assert(encrypted_size > 0); /* This is obviously true, since 4111 is
* greater than 0, but its truth is not
* obvious to all analysis tools. */
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 4095);
+ tt_int_op(decrypted_size,==, 4095);
tt_assert(decrypted_size > 0);
- test_memeq(plain, decrypted1, 4095);
+ tt_mem_op(plain,==, decrypted1, 4095);
/* Encrypt a second time (with a new random initialization vector). */
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted2, 16 + 4095,
plain, 4095);
- test_eq(encrypted_size, 16 + 4095);
+ tt_int_op(encrypted_size,==, 16 + 4095);
tt_assert(encrypted_size > 0);
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted2, 4095,
encrypted2, encrypted_size);
- test_eq(decrypted_size, 4095);
+ tt_int_op(decrypted_size,==, 4095);
tt_assert(decrypted_size > 0);
- test_memeq(plain, decrypted2, 4095);
- test_memneq(encrypted1, encrypted2, encrypted_size);
+ tt_mem_op(plain,==, decrypted2, 4095);
+ tt_mem_op(encrypted1,!=, encrypted2, encrypted_size);
/* Decrypt with the wrong key. */
decrypted_size = crypto_cipher_decrypt_with_iv(key2, decrypted2, 4095,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 4095);
- test_memneq(plain, decrypted2, decrypted_size);
+ tt_int_op(decrypted_size,==, 4095);
+ tt_mem_op(plain,!=, decrypted2, decrypted_size);
/* Alter the initialization vector. */
encrypted1[0] += 42;
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 4095);
- test_memneq(plain, decrypted2, 4095);
+ tt_int_op(decrypted_size,==, 4095);
+ tt_mem_op(plain,!=, decrypted2, 4095);
/* Special length case: 1. */
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 1,
plain_1, 1);
- test_eq(encrypted_size, 16 + 1);
+ tt_int_op(encrypted_size,==, 16 + 1);
tt_assert(encrypted_size > 0);
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 1,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 1);
+ tt_int_op(decrypted_size,==, 1);
tt_assert(decrypted_size > 0);
- test_memeq(plain_1, decrypted1, 1);
+ tt_mem_op(plain_1,==, decrypted1, 1);
/* Special length case: 15. */
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 15,
plain_15, 15);
- test_eq(encrypted_size, 16 + 15);
+ tt_int_op(encrypted_size,==, 16 + 15);
tt_assert(encrypted_size > 0);
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 15,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 15);
+ tt_int_op(decrypted_size,==, 15);
tt_assert(decrypted_size > 0);
- test_memeq(plain_15, decrypted1, 15);
+ tt_mem_op(plain_15,==, decrypted1, 15);
/* Special length case: 16. */
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 16,
plain_16, 16);
- test_eq(encrypted_size, 16 + 16);
+ tt_int_op(encrypted_size,==, 16 + 16);
tt_assert(encrypted_size > 0);
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 16,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 16);
+ tt_int_op(decrypted_size,==, 16);
tt_assert(decrypted_size > 0);
- test_memeq(plain_16, decrypted1, 16);
+ tt_mem_op(plain_16,==, decrypted1, 16);
/* Special length case: 17. */
encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 17,
plain_17, 17);
- test_eq(encrypted_size, 16 + 17);
+ tt_int_op(encrypted_size,==, 16 + 17);
tt_assert(encrypted_size > 0);
decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 17,
encrypted1, encrypted_size);
- test_eq(decrypted_size, 17);
+ tt_int_op(decrypted_size,==, 17);
tt_assert(decrypted_size > 0);
- test_memeq(plain_17, decrypted1, 17);
+ tt_mem_op(plain_17,==, decrypted1, 17);
done:
/* Free memory. */
@@ -842,34 +1201,35 @@ test_crypto_aes_iv(void *arg)
/** Test base32 decoding. */
static void
-test_crypto_base32_decode(void)
+test_crypto_base32_decode(void *arg)
{
char plain[60], encoded[96 + 1], decoded[60];
int res;
+ (void)arg;
crypto_rand(plain, 60);
/* Encode and decode a random string. */
base32_encode(encoded, 96 + 1, plain, 60);
res = base32_decode(decoded, 60, encoded, 96);
- test_eq(res, 0);
- test_memeq(plain, decoded, 60);
+ tt_int_op(res,==, 0);
+ tt_mem_op(plain,==, decoded, 60);
/* Encode, uppercase, and decode a random string. */
base32_encode(encoded, 96 + 1, plain, 60);
tor_strupper(encoded);
res = base32_decode(decoded, 60, encoded, 96);
- test_eq(res, 0);
- test_memeq(plain, decoded, 60);
+ tt_int_op(res,==, 0);
+ tt_mem_op(plain,==, decoded, 60);
/* Change encoded string and decode. */
if (encoded[0] == 'A' || encoded[0] == 'a')
encoded[0] = 'B';
else
encoded[0] = 'A';
res = base32_decode(decoded, 60, encoded, 96);
- test_eq(res, 0);
- test_memneq(plain, decoded, 60);
+ tt_int_op(res,==, 0);
+ tt_mem_op(plain,!=, decoded, 60);
/* Bad encodings. */
encoded[0] = '!';
res = base32_decode(decoded, 60, encoded, 96);
- test_assert(res < 0);
+ tt_int_op(0, >, res);
done:
;
@@ -1024,7 +1384,7 @@ test_crypto_curve25519_impl(void *arg)
e2k[31] |= (byte & 0x80);
}
curve25519_impl(e1e2k,e1,e2k);
- test_memeq(e1e2k, e2e1k, 32);
+ tt_mem_op(e1e2k,==, e2e1k, 32);
if (loop == loop_max-1) {
break;
}
@@ -1056,11 +1416,11 @@ test_crypto_curve25519_wrappers(void *arg)
curve25519_secret_key_generate(&seckey2, 1);
curve25519_public_key_generate(&pubkey1, &seckey1);
curve25519_public_key_generate(&pubkey2, &seckey2);
- test_assert(curve25519_public_key_is_ok(&pubkey1));
- test_assert(curve25519_public_key_is_ok(&pubkey2));
+ tt_assert(curve25519_public_key_is_ok(&pubkey1));
+ tt_assert(curve25519_public_key_is_ok(&pubkey2));
curve25519_handshake(output1, &seckey1, &pubkey2);
curve25519_handshake(output2, &seckey2, &pubkey1);
- test_memeq(output1, output2, sizeof(output1));
+ tt_mem_op(output1,==, output2, sizeof(output1));
done:
;
@@ -1081,12 +1441,12 @@ test_crypto_curve25519_encode(void *arg)
tt_int_op(CURVE25519_BASE64_PADDED_LEN, ==, strlen(buf));
tt_int_op(0, ==, curve25519_public_from_base64(&key2, buf));
- test_memeq(key1.public_key, key2.public_key, CURVE25519_PUBKEY_LEN);
+ tt_mem_op(key1.public_key,==, key2.public_key, CURVE25519_PUBKEY_LEN);
buf[CURVE25519_BASE64_PADDED_LEN - 1] = '\0';
tt_int_op(CURVE25519_BASE64_PADDED_LEN-1, ==, strlen(buf));
tt_int_op(0, ==, curve25519_public_from_base64(&key3, buf));
- test_memeq(key1.public_key, key3.public_key, CURVE25519_PUBKEY_LEN);
+ tt_mem_op(key1.public_key,==, key3.public_key, CURVE25519_PUBKEY_LEN);
/* Now try bogus parses. */
strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$=", sizeof(buf));
@@ -1122,10 +1482,10 @@ test_crypto_curve25519_persist(void *arg)
tt_str_op(tag,==,"testing");
tor_free(tag);
- test_memeq(keypair.pubkey.public_key,
+ tt_mem_op(keypair.pubkey.public_key,==,
keypair2.pubkey.public_key,
CURVE25519_PUBKEY_LEN);
- test_memeq(keypair.seckey.secret_key,
+ tt_mem_op(keypair.seckey.secret_key,==,
keypair2.seckey.secret_key,
CURVE25519_SECKEY_LEN);
@@ -1137,11 +1497,11 @@ test_crypto_curve25519_persist(void *arg)
tt_assert(fast_memeq(content, "== c25519v1: testing ==", taglen));
tt_assert(tor_mem_is_zero(content+taglen, 32-taglen));
cp = content + 32;
- test_memeq(keypair.seckey.secret_key,
+ tt_mem_op(keypair.seckey.secret_key,==,
cp,
CURVE25519_SECKEY_LEN);
cp += CURVE25519_SECKEY_LEN;
- test_memeq(keypair.pubkey.public_key,
+ tt_mem_op(keypair.pubkey.public_key,==,
cp,
CURVE25519_SECKEY_LEN);
@@ -1161,7 +1521,362 @@ test_crypto_curve25519_persist(void *arg)
tor_free(tag);
}
-#endif
+static void
+test_crypto_ed25519_simple(void *arg)
+{
+ ed25519_keypair_t kp1, kp2;
+ ed25519_public_key_t pub1, pub2;
+ ed25519_secret_key_t sec1, sec2;
+ ed25519_signature_t sig1, sig2;
+ const uint8_t msg[] =
+ "GNU will be able to run Unix programs, "
+ "but will not be identical to Unix.";
+ const uint8_t msg2[] =
+ "Microsoft Windows extends the features of the DOS operating system, "
+ "yet is compatible with most existing applications that run under DOS.";
+ size_t msg_len = strlen((const char*)msg);
+ size_t msg2_len = strlen((const char*)msg2);
+
+ (void)arg;
+
+ tt_int_op(0, ==, ed25519_secret_key_generate(&sec1, 0));
+ tt_int_op(0, ==, ed25519_secret_key_generate(&sec2, 1));
+
+ tt_int_op(0, ==, ed25519_public_key_generate(&pub1, &sec1));
+ tt_int_op(0, ==, ed25519_public_key_generate(&pub2, &sec1));
+
+ tt_mem_op(pub1.pubkey, ==, pub2.pubkey, sizeof(pub1.pubkey));
+
+ memcpy(&kp1.pubkey, &pub1, sizeof(pub1));
+ memcpy(&kp1.seckey, &sec1, sizeof(sec1));
+ tt_int_op(0, ==, ed25519_sign(&sig1, msg, msg_len, &kp1));
+ tt_int_op(0, ==, ed25519_sign(&sig2, msg, msg_len, &kp1));
+
+ /* Ed25519 signatures are deterministic */
+ tt_mem_op(sig1.sig, ==, sig2.sig, sizeof(sig1.sig));
+
+ /* Basic signature is valid. */
+ tt_int_op(0, ==, ed25519_checksig(&sig1, msg, msg_len, &pub1));
+
+ /* Altered signature doesn't work. */
+ sig1.sig[0] ^= 3;
+ tt_int_op(-1, ==, ed25519_checksig(&sig1, msg, msg_len, &pub1));
+
+ /* Wrong public key doesn't work. */
+ tt_int_op(0, ==, ed25519_public_key_generate(&pub2, &sec2));
+ tt_int_op(-1, ==, ed25519_checksig(&sig2, msg, msg_len, &pub2));
+
+ /* Wrong message doesn't work. */
+ tt_int_op(0, ==, ed25519_checksig(&sig2, msg, msg_len, &pub1));
+ tt_int_op(-1, ==, ed25519_checksig(&sig2, msg, msg_len-1, &pub1));
+ tt_int_op(-1, ==, ed25519_checksig(&sig2, msg2, msg2_len, &pub1));
+
+ /* Batch signature checking works with some bad. */
+ tt_int_op(0, ==, ed25519_keypair_generate(&kp2, 0));
+ tt_int_op(0, ==, ed25519_sign(&sig1, msg, msg_len, &kp2));
+ {
+ ed25519_checkable_t ch[] = {
+ { &pub1, sig2, msg, msg_len }, /*ok*/
+ { &pub1, sig2, msg, msg_len-1 }, /*bad*/
+ { &kp2.pubkey, sig2, msg2, msg2_len }, /*bad*/
+ { &kp2.pubkey, sig1, msg, msg_len }, /*ok*/
+ };
+ int okay[4];
+ tt_int_op(-2, ==, ed25519_checksig_batch(okay, ch, 4));
+ tt_int_op(okay[0], ==, 1);
+ tt_int_op(okay[1], ==, 0);
+ tt_int_op(okay[2], ==, 0);
+ tt_int_op(okay[3], ==, 1);
+ tt_int_op(-2, ==, ed25519_checksig_batch(NULL, ch, 4));
+ }
+
+ /* Batch signature checking works with all good. */
+ {
+ ed25519_checkable_t ch[] = {
+ { &pub1, sig2, msg, msg_len }, /*ok*/
+ { &kp2.pubkey, sig1, msg, msg_len }, /*ok*/
+ };
+ int okay[2];
+ tt_int_op(0, ==, ed25519_checksig_batch(okay, ch, 2));
+ tt_int_op(okay[0], ==, 1);
+ tt_int_op(okay[1], ==, 1);
+ tt_int_op(0, ==, ed25519_checksig_batch(NULL, ch, 2));
+ }
+
+ done:
+ ;
+}
+
+static void
+test_crypto_ed25519_test_vectors(void *arg)
+{
+ char *mem_op_hex_tmp=NULL;
+ int i;
+ struct {
+ const char *sk;
+ const char *pk;
+ const char *sig;
+ const char *msg;
+ } items[] = {
+ /* These test vectors were generated with the "ref" implementation of
+ * ed25519 from SUPERCOP-20130419 */
+ { "4c6574277320686f706520746865726520617265206e6f206275677320696e20",
+ "f3e0e493b30f56e501aeb868fc912fe0c8b76621efca47a78f6d75875193dd87",
+ "b5d7fd6fd3adf643647ce1fe87a2931dedd1a4e38e6c662bedd35cdd80bfac51"
+ "1b2c7d1ee6bd929ac213014e1a8dc5373854c7b25dbe15ec96bf6c94196fae06",
+ "506c6561736520657863757365206d7920667269656e642e2048652069736e2774"
+ "204e554c2d7465726d696e617465642e"
+ },
+
+ { "74686520696d706c656d656e746174696f6e20776869636820617265206e6f74",
+ "407f0025a1e1351a4cb68e92f5c0ebaf66e7aaf93a4006a4d1a66e3ede1cfeac",
+ "02884fde1c3c5944d0ecf2d133726fc820c303aae695adceabf3a1e01e95bf28"
+ "da88c0966f5265e9c6f8edc77b3b96b5c91baec3ca993ccd21a3f64203600601",
+ "506c6561736520657863757365206d7920667269656e642e2048652069736e2774"
+ "204e554c2d7465726d696e617465642e"
+ },
+ { "6578706f73656420627920456e676c697368207465787420617320696e707574",
+ "61681cb5fbd69f9bc5a462a21a7ab319011237b940bc781cdc47fcbe327e7706",
+ "6a127d0414de7510125d4bc214994ffb9b8857a46330832d05d1355e882344ad"
+ "f4137e3ca1f13eb9cc75c887ef2309b98c57528b4acd9f6376c6898889603209",
+ "506c6561736520657863757365206d7920667269656e642e2048652069736e2774"
+ "204e554c2d7465726d696e617465642e"
+ },
+
+ /* These come from "sign.input" in ed25519's page */
+ { "5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef9",
+ "6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257",
+ "0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258"
+ "c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e",
+ "5a8d9d0a22357e6655f9c785"
+ },
+ { "940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800",
+ "a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd",
+ "d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d"
+ "640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c",
+ "b87d3813e03f58cf19fd0b6395"
+ },
+ { "9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738",
+ "cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291",
+ "6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0"
+ "671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06",
+ "55c7fa434f5ed8cdec2b7aeac173",
+ },
+ { "d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300",
+ "fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5",
+ "f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f3550395"
+ "1fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00",
+ "0a688e79be24f866286d4646b5d81c"
+ },
+
+ { NULL, NULL, NULL, NULL}
+ };
+
+ (void)arg;
+
+ for (i = 0; items[i].pk; ++i) {
+ ed25519_keypair_t kp;
+ ed25519_signature_t sig;
+ uint8_t sk_seed[32];
+ uint8_t *msg;
+ size_t msg_len;
+ base16_decode((char*)sk_seed, sizeof(sk_seed),
+ items[i].sk, 64);
+ ed25519_secret_key_from_seed(&kp.seckey, sk_seed);
+ tt_int_op(0, ==, ed25519_public_key_generate(&kp.pubkey, &kp.seckey));
+ test_memeq_hex(kp.pubkey.pubkey, items[i].pk);
+
+ msg_len = strlen(items[i].msg) / 2;
+ msg = tor_malloc(msg_len);
+ base16_decode((char*)msg, msg_len, items[i].msg, strlen(items[i].msg));
+
+ tt_int_op(0, ==, ed25519_sign(&sig, msg, msg_len, &kp));
+ test_memeq_hex(sig.sig, items[i].sig);
+
+ tor_free(msg);
+ }
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_ed25519_encode(void *arg)
+{
+ char buf[ED25519_BASE64_LEN+1];
+ ed25519_keypair_t kp;
+ ed25519_public_key_t pk;
+ char *mem_op_hex_tmp = NULL;
+ (void) arg;
+
+ /* Test roundtrip. */
+ tt_int_op(0, ==, ed25519_keypair_generate(&kp, 0));
+ tt_int_op(0, ==, ed25519_public_to_base64(buf, &kp.pubkey));
+ tt_int_op(ED25519_BASE64_LEN, ==, strlen(buf));
+ tt_int_op(0, ==, ed25519_public_from_base64(&pk, buf));
+ tt_mem_op(kp.pubkey.pubkey, ==, pk.pubkey, ED25519_PUBKEY_LEN);
+
+ /* Test known value. */
+ tt_int_op(0, ==, ed25519_public_from_base64(&pk,
+ "lVIuIctLjbGZGU5wKMNXxXlSE3cW4kaqkqm04u6pxvM"));
+ test_memeq_hex(pk.pubkey,
+ "95522e21cb4b8db199194e7028c357c57952137716e246aa92a9b4e2eea9c6f3");
+
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+
+static void
+test_crypto_ed25519_convert(void *arg)
+{
+ const uint8_t msg[] =
+ "The eyes are not here / There are no eyes here.";
+ const int N = 30;
+ int i;
+ (void)arg;
+
+ for (i = 0; i < N; ++i) {
+ curve25519_keypair_t curve25519_keypair;
+ ed25519_keypair_t ed25519_keypair;
+ ed25519_public_key_t ed25519_pubkey;
+
+ int bit=0;
+ ed25519_signature_t sig;
+
+ tt_int_op(0,==,curve25519_keypair_generate(&curve25519_keypair, i&1));
+ tt_int_op(0,==,ed25519_keypair_from_curve25519_keypair(
+ &ed25519_keypair, &bit, &curve25519_keypair));
+ tt_int_op(0,==,ed25519_public_key_from_curve25519_public_key(
+ &ed25519_pubkey, &curve25519_keypair.pubkey, bit));
+ tt_mem_op(ed25519_pubkey.pubkey, ==, ed25519_keypair.pubkey.pubkey, 32);
+
+ tt_int_op(0,==,ed25519_sign(&sig, msg, sizeof(msg), &ed25519_keypair));
+ tt_int_op(0,==,ed25519_checksig(&sig, msg, sizeof(msg),
+ &ed25519_pubkey));
+
+ tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg)-1,
+ &ed25519_pubkey));
+ sig.sig[0] ^= 15;
+ tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg),
+ &ed25519_pubkey));
+ }
+
+ done:
+ ;
+}
+
+static void
+test_crypto_ed25519_blinding(void *arg)
+{
+ const uint8_t msg[] =
+ "Eyes I dare not meet in dreams / In death's dream kingdom";
+
+ const int N = 30;
+ int i;
+ (void)arg;
+
+ for (i = 0; i < N; ++i) {
+ uint8_t blinding[32];
+ ed25519_keypair_t ed25519_keypair;
+ ed25519_keypair_t ed25519_keypair_blinded;
+ ed25519_public_key_t ed25519_pubkey_blinded;
+
+ ed25519_signature_t sig;
+
+ crypto_rand((char*) blinding, sizeof(blinding));
+
+ tt_int_op(0,==,ed25519_keypair_generate(&ed25519_keypair, 0));
+ tt_int_op(0,==,ed25519_keypair_blind(&ed25519_keypair_blinded,
+ &ed25519_keypair, blinding));
+
+ tt_int_op(0,==,ed25519_public_blind(&ed25519_pubkey_blinded,
+ &ed25519_keypair.pubkey, blinding));
+
+ tt_mem_op(ed25519_pubkey_blinded.pubkey, ==,
+ ed25519_keypair_blinded.pubkey.pubkey, 32);
+
+ tt_int_op(0,==,ed25519_sign(&sig, msg, sizeof(msg),
+ &ed25519_keypair_blinded));
+
+ tt_int_op(0,==,ed25519_checksig(&sig, msg, sizeof(msg),
+ &ed25519_pubkey_blinded));
+
+ tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg)-1,
+ &ed25519_pubkey_blinded));
+ sig.sig[0] ^= 15;
+ tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg),
+ &ed25519_pubkey_blinded));
+ }
+
+ done:
+ ;
+}
+
+static void
+test_crypto_ed25519_testvectors(void *arg)
+{
+ unsigned i;
+ char *mem_op_hex_tmp = NULL;
+ (void)arg;
+
+ for (i = 0; i < ARRAY_LENGTH(ED25519_SECRET_KEYS); ++i) {
+ uint8_t sk[32];
+ ed25519_secret_key_t esk;
+ ed25519_public_key_t pk, blind_pk, pkfromcurve;
+ ed25519_keypair_t keypair, blind_keypair;
+ curve25519_keypair_t curvekp;
+ uint8_t blinding_param[32];
+ ed25519_signature_t sig;
+ int sign;
+
+#define DECODE(p,s) base16_decode((char*)(p),sizeof(p),(s),strlen(s))
+#define EQ(a,h) test_memeq_hex((const char*)(a), (h))
+
+ tt_int_op(0, ==, DECODE(sk, ED25519_SECRET_KEYS[i]));
+ tt_int_op(0, ==, DECODE(blinding_param, ED25519_BLINDING_PARAMS[i]));
+
+ tt_int_op(0, ==, ed25519_secret_key_from_seed(&esk, sk));
+ EQ(esk.seckey, ED25519_EXPANDED_SECRET_KEYS[i]);
+
+ tt_int_op(0, ==, ed25519_public_key_generate(&pk, &esk));
+ EQ(pk.pubkey, ED25519_PUBLIC_KEYS[i]);
+
+ memcpy(&curvekp.seckey.secret_key, esk.seckey, 32);
+ curve25519_public_key_generate(&curvekp.pubkey, &curvekp.seckey);
+
+ tt_int_op(0, ==,
+ ed25519_keypair_from_curve25519_keypair(&keypair, &sign, &curvekp));
+ tt_int_op(0, ==, ed25519_public_key_from_curve25519_public_key(
+ &pkfromcurve, &curvekp.pubkey, sign));
+ tt_mem_op(keypair.pubkey.pubkey, ==, pkfromcurve.pubkey, 32);
+ EQ(curvekp.pubkey.public_key, ED25519_CURVE25519_PUBLIC_KEYS[i]);
+
+ /* Self-signing */
+ memcpy(&keypair.seckey, &esk, sizeof(esk));
+ memcpy(&keypair.pubkey, &pk, sizeof(pk));
+
+ tt_int_op(0, ==, ed25519_sign(&sig, pk.pubkey, 32, &keypair));
+
+ EQ(sig.sig, ED25519_SELF_SIGNATURES[i]);
+
+ /* Blinding */
+ tt_int_op(0, ==,
+ ed25519_keypair_blind(&blind_keypair, &keypair, blinding_param));
+ tt_int_op(0, ==,
+ ed25519_public_blind(&blind_pk, &pk, blinding_param));
+
+ EQ(blind_keypair.seckey.seckey, ED25519_BLINDED_SECRET_KEYS[i]);
+ EQ(blind_pk.pubkey, ED25519_BLINDED_PUBLIC_KEYS[i]);
+
+ tt_mem_op(blind_pk.pubkey, ==, blind_keypair.pubkey.pubkey, 32);
+
+#undef DECODE
+#undef EQ
+ }
+ done:
+ tor_free(mem_op_hex_tmp);
+}
+#endif /* CURVE25519_ENABLED */
static void
test_crypto_siphash(void *arg)
@@ -1276,7 +1991,7 @@ static const struct testcase_setup_t pass_data = {
};
#define CRYPTO_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_crypto_ ## name }
+ { #name, test_crypto_ ## name , 0, NULL, NULL }
struct testcase_t crypto_tests[] = {
CRYPTO_LEGACY(formats),
@@ -1288,7 +2003,23 @@ struct testcase_t crypto_tests[] = {
{ "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
CRYPTO_LEGACY(digests),
CRYPTO_LEGACY(dh),
- CRYPTO_LEGACY(s2k),
+ CRYPTO_LEGACY(s2k_rfc2440),
+#ifdef HAVE_LIBSCRYPT_H
+ { "s2k_scrypt", test_crypto_s2k_general, 0, &pass_data,
+ (void*)"scrypt" },
+ { "s2k_scrypt_low", test_crypto_s2k_general, 0, &pass_data,
+ (void*)"scrypt-low" },
+#endif
+ { "s2k_pbkdf2", test_crypto_s2k_general, 0, &pass_data,
+ (void*)"pbkdf2" },
+ { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &pass_data,
+ (void*)"rfc2440" },
+ { "s2k_rfc2440_legacy", test_crypto_s2k_general, 0, &pass_data,
+ (void*)"rfc2440-legacy" },
+ { "s2k_errors", test_crypto_s2k_errors, 0, NULL, NULL },
+ { "scrypt_vectors", test_crypto_scrypt_vectors, 0, NULL, NULL },
+ { "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
+ { "pwbox", test_crypto_pwbox, 0, NULL, NULL },
{ "aes_iv_AES", test_crypto_aes_iv, TT_FORK, &pass_data, (void*)"aes" },
{ "aes_iv_EVP", test_crypto_aes_iv, TT_FORK, &pass_data, (void*)"evp" },
CRYPTO_LEGACY(base32_decode),
@@ -1300,6 +2031,12 @@ struct testcase_t crypto_tests[] = {
{ "curve25519_wrappers", test_crypto_curve25519_wrappers, 0, NULL, NULL },
{ "curve25519_encode", test_crypto_curve25519_encode, 0, NULL, NULL },
{ "curve25519_persist", test_crypto_curve25519_persist, 0, NULL, NULL },
+ { "ed25519_simple", test_crypto_ed25519_simple, 0, NULL, NULL },
+ { "ed25519_test_vectors", test_crypto_ed25519_test_vectors, 0, NULL, NULL },
+ { "ed25519_encode", test_crypto_ed25519_encode, 0, NULL, NULL },
+ { "ed25519_convert", test_crypto_ed25519_convert, 0, NULL, NULL },
+ { "ed25519_blinding", test_crypto_ed25519_blinding, 0, NULL, NULL },
+ { "ed25519_testvectors", test_crypto_ed25519_testvectors, 0, NULL, NULL },
#endif
{ "siphash", test_crypto_siphash, 0, NULL, NULL },
END_OF_TESTCASES
diff --git a/src/test/test_descriptors.inc b/src/test/test_descriptors.inc
new file mode 100644
index 0000000000..ecbccbd43a
--- /dev/null
+++ b/src/test/test_descriptors.inc
@@ -0,0 +1,305 @@
+const char TEST_DESCRIPTORS[] =
+"@uploaded-at 2014-06-08 19:20:11\n"
+"@source \"127.0.0.1\"\n"
+"router test000a 127.0.0.1 5000 0 7000\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint C7E7 CCB8 179F 8CC3 7F5C 8A04 2B3A 180B 934B 14BA\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest 67A152A4C7686FB07664F872620635F194D76D95\n"
+"caches-extra-info\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAOuBUIEBARMkkka/TGyaQNgUEDLP0KG7sy6KNQTNOlZHUresPr/vlVjo\n"
+"HPpLMfu9M2z18c51YX/muWwY9x4MyQooD56wI4+AqXQcJRwQfQlPn3Ay82uZViA9\n"
+"DpBajRieLlKKkl145KjArpD7F5BVsqccvjErgFYXvhhjSrx7BVLnAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAN6NLnSxWQnFXxqZi5D3b0BMgV6y9NJLGjYQVP+eWtPZWgqyv4zeYsqv\n"
+"O9y6c5lvxyUxmNHfoAbe/s8f2Vf3/YaC17asAVSln4ktrr3e9iY74a9RMWHv1Gzk\n"
+"3042nMcqj3PEhRN0PoLkcOZNjjmNbaqki6qy9bWWZDNTdo+uI44dAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"contact auth0@test.test\n"
+"ntor-onion-key pK4bs08ERYN591jj7ca17Rn9Q02TIEfhnjR6hSq+fhU=\n"
+"reject *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"rx88DuM3Y7tODlHNDDEVzKpwh3csaG1or+T4l2Xs1oq3iHHyPEtB6QTLYrC60trG\n"
+"aAPsj3DEowGfjga1b248g2dtic8Ab+0exfjMm1RHXfDam5TXXZU3A0wMyoHjqHuf\n"
+"eChGPgFNUvEc+5YtD27qEDcUjcinYztTs7/dzxBT4PE=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:11\n"
+"@source \"127.0.0.1\"\n"
+"router test001a 127.0.0.1 5001 0 7001\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint 35DA 711C FC62 F88B C243 DE32 DC0B C28A 3F62 2610\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest 9E12278D6CF7608071FE98CE9DCEE48FA264518A\n"
+"caches-extra-info\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAPbyUrorqoXMW4oezqd307ZGxgobqvQs2nb3TdQyWrwsHtJmS3utdrJS\n"
+"xJUZPNHOQ2hrDWW1VvevYqRTGeXGZr9TDZ3+t/gVUttqYRhuzzgEKVAZSsTo5ctO\n"
+"QNHnzJ6Xx/w/trhWqPTeJ7R0TCyAbWW7aE3KaKdwvZilRZp/oRUnAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBALwOJ7XZHBnjJEuwF3Os6eashNbTH9YnH8TBZBdKgu3iFJYqDslcMIPX\n"
+"gWCJ9apPHyh1+/8OLRWeEYlwoZzgGi0rjm/+BNeOOmJbjfyjk97DuB9/2O5zr1BM\n"
+"CvOHqQSzMD+vz1ebvfM039a2mO8lXruUFPZQaFVxk8371XP2khqhAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"contact auth1@test.test\n"
+"ntor-onion-key t5bI1ksTdigOksMKRHUDwx/34ajEvDN1IpArOxIEWgk=\n"
+"reject *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"KtMW7A/pzu+np6aKJSy6d7drIb4yjz8SPCo+oQNxj2IqNHJir2O2nWu69xy+K0c1\n"
+"RL05KkcDaYzr5hC80FD1H+sTpGYD28SPkQkzPw+0pReSDl93pVXh0rU6Cdcm75FC\n"
+"t0UZzDt4TsMuFB0ZYpM3phKcQPpiDG6aR0LskL/YUvY=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:11\n"
+"@source \"127.0.0.1\"\n"
+"router test004r 127.0.0.1 5004 0 7004\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:10\n"
+"fingerprint CC6A 48BD 52BD 9A2C 6670 5863 AC31 AE17 6E63 8B02\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest B5CC249CEF394B5AFCA0C77FA7D5605615FA487C\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAMze36Hupy7HACcF3TMv5mJuZbx3d3cS0WYLl6vTeChBgpS5CEXq6zIu\n"
+"d31YmtUcxH6fOjDOudhbnXuoh1nH4CP+LocVHAdlGG1giAm7u8yZudVvVJiIqFgQ\n"
+"wVDcWx8LbGCi5P9J/ZPKAIVsSyS7xkOqHjz3VMo/uYLbQCFAwfkdAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAM/qGP365x6bH+ug7rKVy7V5lC9Ff2Jfk0wlTFIzzwn+DMSG6xDvulKe\n"
+"wcIzgGNdQu7qlKlQUif3GPMr0KSS32cRsmoRQJcsm9+lGUK871NyZ8AyrHT+LhyF\n"
+"cs718P0iN5yKF2FikNr727kEANCzvC1l9eP4qF5GGzsNtglbJ7bTAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"ntor-onion-key a9Pavqnx7DFhMWUO0d17qF9Py8+iie4FnxTHaTgfIXY=\n"
+"reject *:25\n"
+"reject *:119\n"
+"reject *:135-139\n"
+"reject *:445\n"
+"reject *:563\n"
+"reject *:1214\n"
+"reject *:4661-4666\n"
+"reject *:6346-6429\n"
+"reject *:6699\n"
+"reject *:6881-6999\n"
+"accept *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"HVW7kjBgEt+Qdvcrq+NQE1F9B8uV9D38KA2Bp6cYHLWCxL6N4GS8JQqbOEtnqaj7\n"
+"Vxrv7uy1Fzb15Zr+1sUVMxNv+LLRfr+JzfETMNYVkYDrNgr1cAAVEQzFWbIziond\n"
+"xMFp64yjEW9/I+82lb5GBZEiKdEd4QqWMmQosoYMTM8=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:12\n"
+"@source \"127.0.0.1\"\n"
+"router test002a 127.0.0.1 5002 0 7002\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint 29C7 BBB6 C437 32D5 BDF1 5671 F5C5 F1FB 6E36 4B47\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest 9BB181EA86E0130680C3CC04AD7DE4C341ADC2C7\n"
+"caches-extra-info\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBALNH19oF8Ajf+djlH/g7L+enFBf5Wwjmf3bPwNKWZ9G+B+Lg8SpfhZiw\n"
+"rUqi7h21f45BV/dN05dK6leWD8rj1T9kuM9TKBOEZxIWeq7zbXihyu4XPxP4FNTS\n"
+"+0G7BhdP4biALENmeyLhUCZaw5Ic/jFkHT4gV9S0iVZiEDwC9twXAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBALeyQGMQBHgTxpO/i30uHjflTm9MNi3ZBNcOKpvBXWYgY42qTqOZ7Uam\n"
+"c5pmZhTLrQ1W8XlGDw8Cl8ktZ0ylodLZyUNajBtJvSFWTb8iwdZsshW6Ahb8TyfI\n"
+"Y7MwTlQ/7xw4mj1NEaui6bwGgEZUs18RTqhDrUc2Mcj1Yf61Rq+7AgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"contact auth2@test.test\n"
+"ntor-onion-key ukR41RjtiZ69KO0SrFTvL0LoZK/ZTT01FQWmCXTCUlE=\n"
+"reject *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"IY2s/RY4tdahrgfGG+vW7lOvpfofoxxSo7guGpSKGxVApiroCQtumoYifnnJ88G2\n"
+"K4IbxwEO8pgO8fnz1mibblUWw2vdDNjCifc1wtXJUE+ONA0UcLRlfQ94GbL8h2PG\n"
+"72z6i1+NN0QahXMk7MUbzI7bOXTJOiO8e2Zjk9vRnxI=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:12\n"
+"@source \"127.0.0.1\"\n"
+"router test006r 127.0.0.1 5006 0 7006\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint 829B 3FAA A42B 605A EB0B F380 8F32 8ED1 73E7 0D25\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest 7ECB757002EB9B5838B13AE6F2357A5E585131B8\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBALsNBChcLVndlS4HNXL3hxBJVgXctATz6yXcJt3bkDB5cjv7Q9fqN3Ue\n"
+"j3SI1OUBx4YrLcSLD/hELHVilLrrfbaraAFfAsydlRLjTVcMRx5FFlDd0E7TAadc\n"
+"71CkTipNnjwqz1mTRKkEFeepnh/JaFDidY9ER1rMBA5JRyBvqrD9AgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAPgipA8yLj1kqrMlAH7cK7IQEdmqmfNHGXdkYQ+TKtfLh0zeEIvvh9yh\n"
+"k+vKHS+HVoHo3tecB9QjJyDyyJTiETXCupSOY+ebG648JADAvv8v1WiE+KBXtjpl\n"
+"qgDTrDj5CwGuY6cvQdej5yg1UAVlMMZSg3thL3tCYtQbOq66lAlnAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"ntor-onion-key q02F3AQsCX7+zXNpfTqBF8O8lusPhRJpQVxOnBvbOwc=\n"
+"reject *:25\n"
+"reject *:119\n"
+"reject *:135-139\n"
+"reject *:445\n"
+"reject *:563\n"
+"reject *:1214\n"
+"reject *:4661-4666\n"
+"reject *:6346-6429\n"
+"reject *:6699\n"
+"reject *:6881-6999\n"
+"accept *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"L1fdgoN/eXgdzIIXO63W4yGoC9lRozMU+T0Fimhd/XFV8qxeUT83Vgf63vxLUHIb\n"
+"D4a80Wj7Pm4y5a766qLGXxlz2FYjCdkp070UpgZneB+VifUlFd/bNAjsiYTstBKM\n"
+"EI2L0mhl9d/7KK8vgtadHdX1z1u7QjyF6ccnzhfqeiY=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:12\n"
+"@source \"127.0.0.1\"\n"
+"router test003r 127.0.0.1 5003 0 7003\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint 71FD 3A35 F705 8020 D595 B711 D52A 9A0A 99BB B467\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest 3796BE0A95B699595445DFD3453CA2074E75BCE8\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAL44ctIioIfCYFzMTYNfK5qFAPGGUpsAFmS8pThQEY/tJU14+frJDBrC\n"
+"BkLvBs05Bw7xOUb0f2geiYGowBA6028smiq5HzTO7Kaga8vfV7AnANPX+n9cfHCr\n"
+"/2cMnKkT/GZzpdk0WbUw5Kc/G1ATIPFQHA8gZAi1fsSIDDn3GRV5AgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBALlPo5AI1mVTi+194yOSf40caoFlxSTfXt8KjGVa1dO/bpX7L3noOjYg\n"
+"goU4Aqim7BHmBWQDE/tZNTrchFoLQFHi9N4pv/0ND3sY904pzqGpe3FeTuU8P9Jg\n"
+"q2w3MeO3GwG8CJf4FOdSkgi8UKkJhOld4g4kViQbrFLXfdFvnT/zAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"ntor-onion-key qluYCRrsesOTkavCLnNK6H1ToywyDquCyYeP0h/qol4=\n"
+"reject *:25\n"
+"reject *:119\n"
+"reject *:135-139\n"
+"reject *:445\n"
+"reject *:563\n"
+"reject *:1214\n"
+"reject *:4661-4666\n"
+"reject *:6346-6429\n"
+"reject *:6699\n"
+"reject *:6881-6999\n"
+"accept *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"d09K7rW/OpVzoUpfZXJuJW7a+P4pROCOZTgvDUIy/Nv+EAjcYqv95PlJ8cAMqnn3\n"
+"1oQibRmmQwn0OmG5cB8NaZiueaVIRheGzHEM8rndpHn5oFXdFvV7KKjScvfuBbTk\n"
+"RYME8XyawRaqsEZnwirDDlZuiZOjdQs8bbGsko3grJE=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:12\n"
+"@source \"127.0.0.1\"\n"
+"router test005r 127.0.0.1 5005 0 7005\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint EB6E 42ED E6BF 5EE0 19F5 EFC1 53AD 094C 1327 7B76\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest C031EE4E1AE826C1E3C4E21D81C961869E63F5D2\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAMd9Fm4KTSjFDzEABPZ1fwBCC2DNgee6nAmlde8FRbCVfcIHRiJyv9YG\n"
+"h530yUJal3hBfiWwy/SBA4LDz1flNCEwJm81s3waj4T9c676dAOLPcnOcJM5SbaQ\n"
+"hYPDrIZLEZHAk+IoM+avKYYocwCJXwx6WTtsedF0wJBZ9mQAJERJAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAKT7ldhV43S1CgoER/pU0Rigf0NzcSy25DQJrMRQnNmXnL03Dwuv/Iu7\n"
+"dCjgg64odnvSkXHFhkbjGcg8aXikvfbMyZTbsD8NrrP6FS6pfgPgZD9W2TK7QdHI\n"
+"QXwx1IYaaJK4nDUNfJhjrclydEdxmHbO1nLG1aS0ypn/G0EBpOSnAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"ntor-onion-key umFmyRPA0dIsi0CFYCbGIPe2+OUkyslTkKKDEohjQQg=\n"
+"reject *:25\n"
+"reject *:119\n"
+"reject *:135-139\n"
+"reject *:445\n"
+"reject *:563\n"
+"reject *:1214\n"
+"reject *:4661-4666\n"
+"reject *:6346-6429\n"
+"reject *:6699\n"
+"reject *:6881-6999\n"
+"accept *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"JiXEbqPgDPWEb9DzCYINRXfmvMIc/IRtvshS8Vmmn7DW67TrTLKCEAnisGo92gMA\n"
+"bhxGb9G5Mxq/8YqGoqdI2Vp6tfKlz/9AmjHzFAo01y42gafXIdr1oUS2RimA8jfF\n"
+"hwfQkbG0FYEsJrH3EUa8sMhcjsEaohK/kgklMR7OgQY=\n"
+"-----END SIGNATURE-----\n"
+"@uploaded-at 2014-06-08 19:20:12\n"
+"@source \"127.0.0.1\"\n"
+"router test007r 127.0.0.1 5007 0 7007\n"
+"platform Tor 0.2.5.3-alpha-dev on Linux\n"
+"protocols Link 1 2 Circuit 1\n"
+"published 2014-06-08 19:20:11\n"
+"fingerprint DABD 2AAF 8C9F 3B71 7839 9C08 DCD8 CD9D 341D 0002\n"
+"uptime 0\n"
+"bandwidth 1073741824 1073741824 0\n"
+"extra-info-digest F80104A0DFFB4EB429325D41D1F71E5BF8C6C726\n"
+"onion-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAL42fYAriR/JeB/9NpVq5Y5EEHca+ugIpaSdRfbopWDtFjXLEk2jmO5A\n"
+"KoAGIkTKDr7e9101x63H+0Nh/7w3uYs/WqTXEH8/1sHwe+0PY2HL0S6qhlOo6X54\n"
+"EfK0nDDBAWFOpyiAMHRk8JVikKb56+FVIhCJgi1RIbLIiUQK2/kxAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"signing-key\n"
+"-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAKQj2U5hmB68V6NQBqD8DfIkJjovvM8t6nGfYpkT8ORsROnmgI5mjM38\n"
+"cmh5GIjY9RgoOWolLmsWQ4SXtS0FvrPft1M61UMTSHzlrEeuod5KenV7vGlX2TxT\n"
+"0DoA5TL9yY7CmxCk8CNRCtN/g7WocgIiP4KCIiEZ4VE6LIb6sxUnAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n"
+"hidden-service-dir\n"
+"ntor-onion-key 1UBS8rTlL39u9YxRJWhz+GTG1dS15VRi4au1i5qZOyI=\n"
+"reject *:25\n"
+"reject *:119\n"
+"reject *:135-139\n"
+"reject *:445\n"
+"reject *:563\n"
+"reject *:1214\n"
+"reject *:4661-4666\n"
+"reject *:6346-6429\n"
+"reject *:6699\n"
+"reject *:6881-6999\n"
+"accept *:*\n"
+"router-signature\n"
+"-----BEGIN SIGNATURE-----\n"
+"m7xHh+XPdLN+qcMLz1dBAEAmcdCFrtdseMHCc0FyAP2kXdayxqe3o2IOOHN++bTH\n"
+"Y5iHsZembsIJJ+D/d0YEKWKh42TUWCXBu0Gbfc4OcNuR6PFlTWO2wk7rDT3HOiFr\n"
+"pe3wJqZYkLxlBDamROAlMMRe71iag89H/4EulC18opw=\n"
+"-----END SIGNATURE-----\n";
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index c03b63be27..3042ec281f 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -25,55 +25,56 @@
#include "test.h"
static void
-test_dir_nicknames(void)
+test_dir_nicknames(void *arg)
{
- test_assert( is_legal_nickname("a"));
- test_assert(!is_legal_nickname(""));
- test_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
- test_assert(!is_legal_nickname("hyphen-")); /* bad char */
- test_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
- test_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+ (void)arg;
+ tt_assert( is_legal_nickname("a"));
+ tt_assert(!is_legal_nickname(""));
+ tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */
+ tt_assert(!is_legal_nickname("hyphen-")); /* bad char */
+ tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */
+ tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
/* valid */
- test_assert( is_legal_nickname_or_hexdigest(
+ tt_assert( is_legal_nickname_or_hexdigest(
"$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- test_assert( is_legal_nickname_or_hexdigest(
+ tt_assert( is_legal_nickname_or_hexdigest(
"$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
- test_assert( is_legal_nickname_or_hexdigest(
+ tt_assert( is_legal_nickname_or_hexdigest(
"$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred"));
/* too short */
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
/* illegal char */
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
/* hex part too long */
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred"));
/* Bad nickname */
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"));
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-"));
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~"
"abcdefghijklmnoppqrst"));
/* Bad extra char. */
- test_assert(!is_legal_nickname_or_hexdigest(
+ tt_assert(!is_legal_nickname_or_hexdigest(
"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!"));
- test_assert(is_legal_nickname_or_hexdigest("xyzzy"));
- test_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
- test_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
+ tt_assert(is_legal_nickname_or_hexdigest("xyzzy"));
+ tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs"));
+ tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst"));
done:
;
}
/** Run unit tests for router descriptor generation logic. */
static void
-test_dir_formats(void)
+test_dir_formats(void *arg)
{
char *buf = NULL;
char buf2[8192];
@@ -89,10 +90,11 @@ test_dir_formats(void)
or_options_t *options = get_options_mutable();
const addr_policy_t *p;
+ (void)arg;
pk1 = pk_generate(0);
pk2 = pk_generate(1);
- test_assert(pk1 && pk2);
+ tt_assert(pk1 && pk2);
hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
@@ -140,9 +142,9 @@ test_dir_formats(void)
smartlist_add(r2->exit_policy, ex2);
r2->nickname = tor_strdup("Fred");
- test_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
+ tt_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str,
&pk1_str_len));
- test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
+ tt_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
&pk2_str_len));
/* XXXX025 router_dump_to_string should really take this from ri.*/
@@ -150,7 +152,7 @@ test_dir_formats(void)
"<magri@elsewhere.example.com>");
buf = router_dump_router_to_string(r1, pk2);
tor_free(options->ContactInfo);
- test_assert(buf);
+ tt_assert(buf);
strlcpy(buf2, "router Magri 192.168.0.1 9000 0 9003\n"
"or-address [1:2:3:4::]:9999\n"
@@ -160,7 +162,7 @@ test_dir_formats(void)
"protocols Link 1 2 Circuit 1\n"
"published 1970-01-01 00:00:00\n"
"fingerprint ", sizeof(buf2));
- test_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
+ tt_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
strlcat(buf2, fingerprint, sizeof(buf2));
strlcat(buf2, "\nuptime 0\n"
/* XXX the "0" above is hard-coded, but even if we made it reflect
@@ -178,23 +180,23 @@ test_dir_formats(void)
buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
* twice */
- test_streq(buf, buf2);
+ tt_str_op(buf,==, buf2);
tor_free(buf);
buf = router_dump_router_to_string(r1, pk2);
- test_assert(buf);
+ tt_assert(buf);
cp = buf;
rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL);
- test_assert(rp1);
- test_eq(rp1->addr, r1->addr);
- test_eq(rp1->or_port, r1->or_port);
+ tt_assert(rp1);
+ tt_int_op(rp1->addr,==, r1->addr);
+ tt_int_op(rp1->or_port,==, r1->or_port);
//test_eq(rp1->dir_port, r1->dir_port);
- test_eq(rp1->bandwidthrate, r1->bandwidthrate);
- test_eq(rp1->bandwidthburst, r1->bandwidthburst);
- test_eq(rp1->bandwidthcapacity, r1->bandwidthcapacity);
- test_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0);
- test_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0);
- //test_assert(rp1->exit_policy == NULL);
+ tt_int_op(rp1->bandwidthrate,==, r1->bandwidthrate);
+ tt_int_op(rp1->bandwidthburst,==, r1->bandwidthburst);
+ tt_int_op(rp1->bandwidthcapacity,==, r1->bandwidthcapacity);
+ tt_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0);
+ tt_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0);
+ //tt_assert(rp1->exit_policy == NULL);
tor_free(buf);
strlcpy(buf2,
@@ -205,7 +207,7 @@ test_dir_formats(void)
"protocols Link 1 2 Circuit 1\n"
"published 1970-01-01 00:00:05\n"
"fingerprint ", sizeof(buf2));
- test_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1));
+ tt_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1));
strlcat(buf2, fingerprint, sizeof(buf2));
strlcat(buf2, "\nuptime 0\n"
"bandwidth 3000 3000 3000\n", sizeof(buf2));
@@ -224,51 +226,51 @@ test_dir_formats(void)
buf = router_dump_router_to_string(r2, pk1);
buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
* twice */
- test_streq(buf, buf2);
+ tt_str_op(buf,==, buf2);
tor_free(buf);
buf = router_dump_router_to_string(r2, pk1);
cp = buf;
rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL);
- test_assert(rp2);
- test_eq(rp2->addr, r2->addr);
- test_eq(rp2->or_port, r2->or_port);
- test_eq(rp2->dir_port, r2->dir_port);
- test_eq(rp2->bandwidthrate, r2->bandwidthrate);
- test_eq(rp2->bandwidthburst, r2->bandwidthburst);
- test_eq(rp2->bandwidthcapacity, r2->bandwidthcapacity);
+ tt_assert(rp2);
+ tt_int_op(rp2->addr,==, r2->addr);
+ tt_int_op(rp2->or_port,==, r2->or_port);
+ tt_int_op(rp2->dir_port,==, r2->dir_port);
+ tt_int_op(rp2->bandwidthrate,==, r2->bandwidthrate);
+ tt_int_op(rp2->bandwidthburst,==, r2->bandwidthburst);
+ tt_int_op(rp2->bandwidthcapacity,==, r2->bandwidthcapacity);
#ifdef CURVE25519_ENABLED
- test_memeq(rp2->onion_curve25519_pkey->public_key,
+ tt_mem_op(rp2->onion_curve25519_pkey->public_key,==,
r2->onion_curve25519_pkey->public_key,
CURVE25519_PUBKEY_LEN);
#endif
- test_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0);
- test_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0);
+ tt_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0);
+ tt_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0);
- test_eq(smartlist_len(rp2->exit_policy), 2);
+ tt_int_op(smartlist_len(rp2->exit_policy),==, 2);
p = smartlist_get(rp2->exit_policy, 0);
- test_eq(p->policy_type, ADDR_POLICY_ACCEPT);
- test_assert(tor_addr_is_null(&p->addr));
- test_eq(p->maskbits, 0);
- test_eq(p->prt_min, 80);
- test_eq(p->prt_max, 80);
+ tt_int_op(p->policy_type,==, ADDR_POLICY_ACCEPT);
+ tt_assert(tor_addr_is_null(&p->addr));
+ tt_int_op(p->maskbits,==, 0);
+ tt_int_op(p->prt_min,==, 80);
+ tt_int_op(p->prt_max,==, 80);
p = smartlist_get(rp2->exit_policy, 1);
- test_eq(p->policy_type, ADDR_POLICY_REJECT);
- test_assert(tor_addr_eq(&p->addr, &ex2->addr));
- test_eq(p->maskbits, 8);
- test_eq(p->prt_min, 24);
- test_eq(p->prt_max, 24);
+ tt_int_op(p->policy_type,==, ADDR_POLICY_REJECT);
+ tt_assert(tor_addr_eq(&p->addr, &ex2->addr));
+ tt_int_op(p->maskbits,==, 8);
+ tt_int_op(p->prt_min,==, 24);
+ tt_int_op(p->prt_max,==, 24);
#if 0
/* Okay, now for the directories. */
{
fingerprint_list = smartlist_new();
crypto_pk_get_fingerprint(pk2, buf, 1);
- add_fingerprint_to_dir("Magri", buf, fingerprint_list);
+ add_fingerprint_to_dir(buf, fingerprint_list, 0);
crypto_pk_get_fingerprint(pk1, buf, 1);
- add_fingerprint_to_dir("Fred", buf, fingerprint_list);
+ add_fingerprint_to_dir(buf, fingerprint_list, 0);
}
#endif
@@ -293,49 +295,50 @@ test_dir_formats(void)
}
static void
-test_dir_versions(void)
+test_dir_versions(void *arg)
{
tor_version_t ver1;
/* Try out version parsing functionality */
- test_eq(0, tor_version_parse("0.3.4pre2-cvs", &ver1));
- test_eq(0, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_PRE, ver1.status);
- test_eq(2, ver1.patchlevel);
- test_eq(0, tor_version_parse("0.3.4rc1", &ver1));
- test_eq(0, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_RC, ver1.status);
- test_eq(1, ver1.patchlevel);
- test_eq(0, tor_version_parse("1.3.4", &ver1));
- test_eq(1, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_RELEASE, ver1.status);
- test_eq(0, ver1.patchlevel);
- test_eq(0, tor_version_parse("1.3.4.999", &ver1));
- test_eq(1, ver1.major);
- test_eq(3, ver1.minor);
- test_eq(4, ver1.micro);
- test_eq(VER_RELEASE, ver1.status);
- test_eq(999, ver1.patchlevel);
- test_eq(0, tor_version_parse("0.1.2.4-alpha", &ver1));
- test_eq(0, ver1.major);
- test_eq(1, ver1.minor);
- test_eq(2, ver1.micro);
- test_eq(4, ver1.patchlevel);
- test_eq(VER_RELEASE, ver1.status);
- test_streq("alpha", ver1.status_tag);
- test_eq(0, tor_version_parse("0.1.2.4", &ver1));
- test_eq(0, ver1.major);
- test_eq(1, ver1.minor);
- test_eq(2, ver1.micro);
- test_eq(4, ver1.patchlevel);
- test_eq(VER_RELEASE, ver1.status);
- test_streq("", ver1.status_tag);
+ (void)arg;
+ tt_int_op(0,==, tor_version_parse("0.3.4pre2-cvs", &ver1));
+ tt_int_op(0,==, ver1.major);
+ tt_int_op(3,==, ver1.minor);
+ tt_int_op(4,==, ver1.micro);
+ tt_int_op(VER_PRE,==, ver1.status);
+ tt_int_op(2,==, ver1.patchlevel);
+ tt_int_op(0,==, tor_version_parse("0.3.4rc1", &ver1));
+ tt_int_op(0,==, ver1.major);
+ tt_int_op(3,==, ver1.minor);
+ tt_int_op(4,==, ver1.micro);
+ tt_int_op(VER_RC,==, ver1.status);
+ tt_int_op(1,==, ver1.patchlevel);
+ tt_int_op(0,==, tor_version_parse("1.3.4", &ver1));
+ tt_int_op(1,==, ver1.major);
+ tt_int_op(3,==, ver1.minor);
+ tt_int_op(4,==, ver1.micro);
+ tt_int_op(VER_RELEASE,==, ver1.status);
+ tt_int_op(0,==, ver1.patchlevel);
+ tt_int_op(0,==, tor_version_parse("1.3.4.999", &ver1));
+ tt_int_op(1,==, ver1.major);
+ tt_int_op(3,==, ver1.minor);
+ tt_int_op(4,==, ver1.micro);
+ tt_int_op(VER_RELEASE,==, ver1.status);
+ tt_int_op(999,==, ver1.patchlevel);
+ tt_int_op(0,==, tor_version_parse("0.1.2.4-alpha", &ver1));
+ tt_int_op(0,==, ver1.major);
+ tt_int_op(1,==, ver1.minor);
+ tt_int_op(2,==, ver1.micro);
+ tt_int_op(4,==, ver1.patchlevel);
+ tt_int_op(VER_RELEASE,==, ver1.status);
+ tt_str_op("alpha",==, ver1.status_tag);
+ tt_int_op(0,==, tor_version_parse("0.1.2.4", &ver1));
+ tt_int_op(0,==, ver1.major);
+ tt_int_op(1,==, ver1.minor);
+ tt_int_op(2,==, ver1.micro);
+ tt_int_op(4,==, ver1.patchlevel);
+ tt_int_op(VER_RELEASE,==, ver1.status);
+ tt_str_op("",==, ver1.status_tag);
#define tt_versionstatus_op(vs1, op, vs2) \
tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
@@ -368,53 +371,54 @@ test_dir_versions(void)
/* On list, not newer than any on same series. */
test_v_i_o(VS_UNRECOMMENDED,
"0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
- test_eq(0, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
- test_eq(1, tor_version_as_new_as(
+ tt_int_op(0,==, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
+ tt_int_op(1,==, tor_version_as_new_as(
"Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
"sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh",
"0.0.8rc2"));
- test_eq(0, tor_version_as_new_as(
+ tt_int_op(0,==, tor_version_as_new_as(
"Tor 0.0.8 on Darwin 64-121-192-100.c3-0."
"sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2"));
/* Now try svn revisions. */
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
+ tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
"Tor 0.2.1.0-dev (r99)"));
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100) on Banana Jr",
+ tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r100) on Banana Jr",
"Tor 0.2.1.0-dev (r99) on Hal 9000"));
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
+ tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)",
"Tor 0.2.1.0-dev on Colossus"));
- test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
+ tt_int_op(0,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)",
"Tor 0.2.1.0-dev (r100)"));
- test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
+ tt_int_op(0,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP",
"Tor 0.2.1.0-dev (r100) on AM"));
- test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev",
+ tt_int_op(0,==, tor_version_as_new_as("Tor 0.2.1.0-dev",
"Tor 0.2.1.0-dev (r99)"));
- test_eq(1, tor_version_as_new_as("Tor 0.2.1.1",
+ tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.1",
"Tor 0.2.1.0-dev (r99)"));
/* Now try git revisions */
- test_eq(0, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
- test_eq(0, ver1.major);
- test_eq(5, ver1.minor);
- test_eq(6, ver1.micro);
- test_eq(7, ver1.patchlevel);
- test_eq(3, ver1.git_tag_len);
- test_memeq(ver1.git_tag, "\xff\x00\xff", 3);
- test_eq(-1, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
- test_eq(-1, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
- test_eq(0, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
+ tt_int_op(0,==, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
+ tt_int_op(0,==, ver1.major);
+ tt_int_op(5,==, ver1.minor);
+ tt_int_op(6,==, ver1.micro);
+ tt_int_op(7,==, ver1.patchlevel);
+ tt_int_op(3,==, ver1.git_tag_len);
+ tt_mem_op(ver1.git_tag,==, "\xff\x00\xff", 3);
+ tt_int_op(-1,==, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
+ tt_int_op(-1,==, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
+ tt_int_op(0,==, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
done:
;
}
/** Run unit tests for directory fp_pair functions. */
static void
-test_dir_fp_pairs(void)
+test_dir_fp_pairs(void *arg)
{
smartlist_t *sl = smartlist_new();
fp_pair_t *pair;
+ (void)arg;
dir_split_resource_into_fingerprint_pairs(
/* Two pairs, out of order, with one duplicate. */
"73656372657420646174612E0000000000FFFFFF-"
@@ -424,13 +428,13 @@ test_dir_fp_pairs(void)
"48657861646563696d616c2069736e277420736f-"
"676f6f6420666f7220686964696e6720796f7572.z", sl);
- test_eq(smartlist_len(sl), 2);
+ tt_int_op(smartlist_len(sl),==, 2);
pair = smartlist_get(sl, 0);
- test_memeq(pair->first, "Hexadecimal isn't so", DIGEST_LEN);
- test_memeq(pair->second, "good for hiding your", DIGEST_LEN);
+ tt_mem_op(pair->first,==, "Hexadecimal isn't so", DIGEST_LEN);
+ tt_mem_op(pair->second,==, "good for hiding your", DIGEST_LEN);
pair = smartlist_get(sl, 1);
- test_memeq(pair->first, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN);
- test_memeq(pair->second, "Use AES-256 instead.", DIGEST_LEN);
+ tt_mem_op(pair->first,==, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN);
+ tt_mem_op(pair->second,==, "Use AES-256 instead.", DIGEST_LEN);
done:
SMARTLIST_FOREACH(sl, fp_pair_t *, pair, tor_free(pair));
@@ -557,7 +561,7 @@ test_dir_split_fps(void *testdata)
}
static void
-test_dir_measured_bw_kb(void)
+test_dir_measured_bw_kb(void *arg)
{
measured_bw_line_t mbwl;
int i;
@@ -605,16 +609,17 @@ test_dir_measured_bw_kb(void)
"end"
};
+ (void)arg;
for (i = 0; strcmp(lines_fail[i], "end"); i++) {
//fprintf(stderr, "Testing: %s\n", lines_fail[i]);
- test_assert(measured_bw_line_parse(&mbwl, lines_fail[i]) == -1);
+ tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i]) == -1);
}
for (i = 0; strcmp(lines_pass[i], "end"); i++) {
//fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
- test_assert(measured_bw_line_parse(&mbwl, lines_pass[i]) == 0);
- test_assert(mbwl.bw_kb == 1024);
- test_assert(strcmp(mbwl.node_hex,
+ tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i]) == 0);
+ tt_assert(mbwl.bw_kb == 1024);
+ tt_assert(strcmp(mbwl.node_hex,
"557365204145532d32353620696e73746561642e") == 0);
}
@@ -626,7 +631,7 @@ test_dir_measured_bw_kb(void)
/** Do the measured bandwidth cache unit test */
static void
-test_dir_measured_bw_kb_cache(void)
+test_dir_measured_bw_kb_cache(void *arg)
{
/* Initial fake time_t for testing */
time_t curr = MBWC_INIT_TIME;
@@ -637,8 +642,9 @@ test_dir_measured_bw_kb_cache(void)
time_t as_of;
/* First, clear the cache and assert that it's empty */
+ (void)arg;
dirserv_clear_measured_bw_cache();
- test_eq(dirserv_get_measured_bw_cache_size(), 0);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 0);
/*
* Set up test mbwls; none of the dirserv_cache_*() functions care about
* the node_hex field.
@@ -651,56 +657,56 @@ test_dir_measured_bw_kb_cache(void)
mbwl[2].bw_kb = 80;
/* Try caching something */
dirserv_cache_measured_bw(&(mbwl[0]), curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 1);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 1);
/* Okay, let's see if we can retrieve it */
- test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
- test_eq(bw, 20);
- test_eq(as_of, MBWC_INIT_TIME);
+ tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of));
+ tt_int_op(bw,==, 20);
+ tt_int_op(as_of,==, MBWC_INIT_TIME);
/* Try retrieving it without some outputs */
- test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
- test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
- test_eq(bw, 20);
- test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
- test_eq(as_of, MBWC_INIT_TIME);
+ tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL));
+ tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL));
+ tt_int_op(bw,==, 20);
+ tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of));
+ tt_int_op(as_of,==, MBWC_INIT_TIME);
/* Now expire it */
curr += MAX_MEASUREMENT_AGE + 1;
dirserv_expire_measured_bw_cache(curr);
/* Check that the cache is empty */
- test_eq(dirserv_get_measured_bw_cache_size(), 0);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 0);
/* Check that we can't retrieve it */
- test_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
+ tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL));
/* Try caching a few things now */
dirserv_cache_measured_bw(&(mbwl[0]), curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 1);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 1);
curr += MAX_MEASUREMENT_AGE / 4;
dirserv_cache_measured_bw(&(mbwl[1]), curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 2);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 2);
curr += MAX_MEASUREMENT_AGE / 4;
dirserv_cache_measured_bw(&(mbwl[2]), curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 3);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 3);
curr += MAX_MEASUREMENT_AGE / 4 + 1;
/* Do an expire that's too soon to get any of them */
dirserv_expire_measured_bw_cache(curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 3);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 3);
/* Push the oldest one off the cliff */
curr += MAX_MEASUREMENT_AGE / 4;
dirserv_expire_measured_bw_cache(curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 2);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 2);
/* And another... */
curr += MAX_MEASUREMENT_AGE / 4;
dirserv_expire_measured_bw_cache(curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 1);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 1);
/* This should empty it out again */
curr += MAX_MEASUREMENT_AGE / 4;
dirserv_expire_measured_bw_cache(curr);
- test_eq(dirserv_get_measured_bw_cache_size(), 0);
+ tt_int_op(dirserv_get_measured_bw_cache_size(),==, 0);
done:
return;
}
static void
-test_dir_param_voting(void)
+test_dir_param_voting(void *arg)
{
networkstatus_t vote1, vote2, vote3, vote4;
smartlist_t *votes = smartlist_new();
@@ -709,6 +715,7 @@ test_dir_param_voting(void)
/* dirvote_compute_params only looks at the net_params field of the votes,
so that's all we need to set.
*/
+ (void)arg;
memset(&vote1, 0, sizeof(vote1));
memset(&vote2, 0, sizeof(vote2));
memset(&vote3, 0, sizeof(vote3));
@@ -725,87 +732,71 @@ test_dir_param_voting(void)
"abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0);
smartlist_split_string(vote4.net_params,
"ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0);
- test_eq(100, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
- test_eq(222, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
- test_eq(80, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
- test_eq(-8, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
- test_eq(0, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
+ tt_int_op(100,==, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300));
+ tt_int_op(222,==, networkstatus_get_param(&vote4, "foobar", 222, 0, 300));
+ tt_int_op(80,==, networkstatus_get_param(&vote4, "ab", 12, 0, 80));
+ tt_int_op(-8,==, networkstatus_get_param(&vote4, "ab", -12, -100, -8));
+ tt_int_op(0,==, networkstatus_get_param(&vote4, "foobar", 0, -100, 8));
smartlist_add(votes, &vote1);
/* Do the first tests without adding all the other votes, for
* networks without many dirauths. */
- res = dirvote_compute_params(votes, 11, 6);
- test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-99");
- tor_free(res);
-
res = dirvote_compute_params(votes, 12, 2);
- test_streq(res, "");
+ tt_str_op(res,==, "");
tor_free(res);
res = dirvote_compute_params(votes, 12, 1);
- test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-99");
+ tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-99");
tor_free(res);
smartlist_add(votes, &vote2);
- res = dirvote_compute_params(votes, 11, 2);
- test_streq(res, "ab=27 abcd=20 cw=5 x-yz=-99");
- tor_free(res);
-
res = dirvote_compute_params(votes, 12, 2);
- test_streq(res, "ab=27 cw=5 x-yz=-99");
+ tt_str_op(res,==, "ab=27 cw=5 x-yz=-99");
tor_free(res);
res = dirvote_compute_params(votes, 12, 3);
- test_streq(res, "ab=27 cw=5 x-yz=-99");
+ tt_str_op(res,==, "ab=27 cw=5 x-yz=-99");
tor_free(res);
res = dirvote_compute_params(votes, 12, 6);
- test_streq(res, "");
+ tt_str_op(res,==, "");
tor_free(res);
smartlist_add(votes, &vote3);
- res = dirvote_compute_params(votes, 11, 3);
- test_streq(res, "ab=27 abcd=20 c=60 cw=50 x-yz=-9 zzzzz=101");
- tor_free(res);
-
res = dirvote_compute_params(votes, 12, 3);
- test_streq(res, "ab=27 abcd=20 cw=50 x-yz=-9");
+ tt_str_op(res,==, "ab=27 abcd=20 cw=50 x-yz=-9");
tor_free(res);
res = dirvote_compute_params(votes, 12, 5);
- test_streq(res, "cw=50 x-yz=-9");
+ tt_str_op(res,==, "cw=50 x-yz=-9");
tor_free(res);
res = dirvote_compute_params(votes, 12, 9);
- test_streq(res, "cw=50 x-yz=-9");
+ tt_str_op(res,==, "cw=50 x-yz=-9");
tor_free(res);
smartlist_add(votes, &vote4);
- res = dirvote_compute_params(votes, 11, 4);
- test_streq(res, "ab=90 abcd=20 c=1 cw=50 x-yz=-9 zzzzz=101");
- tor_free(res);
-
res = dirvote_compute_params(votes, 12, 4);
- test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9");
+ tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9");
tor_free(res);
res = dirvote_compute_params(votes, 12, 5);
- test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9");
+ tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9");
tor_free(res);
/* Test that the special-cased "at least three dirauths voted for
* this param" logic works as expected. */
res = dirvote_compute_params(votes, 12, 6);
- test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9");
+ tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9");
tor_free(res);
res = dirvote_compute_params(votes, 12, 10);
- test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9");
+ tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9");
tor_free(res);
done:
@@ -837,14 +828,14 @@ static void
test_same_voter(networkstatus_voter_info_t *v1,
networkstatus_voter_info_t *v2)
{
- test_streq(v1->nickname, v2->nickname);
- test_memeq(v1->identity_digest, v2->identity_digest, DIGEST_LEN);
- test_streq(v1->address, v2->address);
- test_eq(v1->addr, v2->addr);
- test_eq(v1->dir_port, v2->dir_port);
- test_eq(v1->or_port, v2->or_port);
- test_streq(v1->contact, v2->contact);
- test_memeq(v1->vote_digest, v2->vote_digest, DIGEST_LEN);
+ tt_str_op(v1->nickname,==, v2->nickname);
+ tt_mem_op(v1->identity_digest,==, v2->identity_digest, DIGEST_LEN);
+ tt_str_op(v1->address,==, v2->address);
+ tt_int_op(v1->addr,==, v2->addr);
+ tt_int_op(v1->dir_port,==, v2->dir_port);
+ tt_int_op(v1->or_port,==, v2->or_port);
+ tt_str_op(v1->contact,==, v2->contact);
+ tt_mem_op(v1->vote_digest,==, v2->vote_digest, DIGEST_LEN);
done:
;
}
@@ -981,7 +972,7 @@ gen_routerstatus_for_v3ns(int idx, time_t now)
break;
default:
/* Shouldn't happen */
- test_assert(0);
+ tt_assert(0);
}
if (vrs) {
vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
@@ -1002,14 +993,14 @@ vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
vote_routerstatus_t *vrs;
const char *msg = NULL;
- test_assert(v);
+ tt_assert(v);
(void)now;
if (voter == 1) {
measured_bw_line_t mbw;
memset(mbw.node_id, 33, sizeof(mbw.node_id));
mbw.bw_kb = 1024;
- test_assert(measured_bw_line_apply(&mbw,
+ tt_assert(measured_bw_line_apply(&mbw,
v->routerstatus_list) == 1);
} else if (voter == 2 || voter == 3) {
/* Monkey around with the list a bit */
@@ -1025,7 +1016,7 @@ vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now)
vote_routerstatus_free(vrs);
vrs = smartlist_get(v->routerstatus_list, 0);
memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN);
- test_assert(router_add_to_routerlist(
+ tt_assert(router_add_to_routerlist(
generate_ri_from_rs(vrs), &msg,0,0) >= 0);
}
}
@@ -1043,9 +1034,9 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
routerstatus_t *rs;
tor_addr_t addr_ipv6;
- test_assert(vrs);
+ tt_assert(vrs);
rs = &(vrs->status);
- test_assert(rs);
+ tt_assert(rs);
/* Split out by digests to test */
if (tor_memeq(rs->identity_digest,
@@ -1054,17 +1045,17 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
DIGEST_LEN) &&
(voter == 1)) {
/* Check the first routerstatus. */
- test_streq(vrs->version, "0.1.2.14");
- test_eq(rs->published_on, now-1500);
- test_streq(rs->nickname, "router2");
- test_memeq(rs->identity_digest,
+ tt_str_op(vrs->version,==, "0.1.2.14");
+ tt_int_op(rs->published_on,==, now-1500);
+ tt_str_op(rs->nickname,==, "router2");
+ tt_mem_op(rs->identity_digest,==,
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
"\x3\x3\x3\x3",
DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
- test_eq(rs->addr, 0x99008801);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 8000);
+ tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
+ tt_int_op(rs->addr,==, 0x99008801);
+ tt_int_op(rs->or_port,==, 443);
+ tt_int_op(rs->dir_port,==, 8000);
/* no flags except "running" (16) and "v2dir" (64) */
tt_u64_op(vrs->flags, ==, U64_LITERAL(80));
} else if (tor_memeq(rs->identity_digest,
@@ -1072,24 +1063,24 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
"\x5\x5\x5\x5",
DIGEST_LEN) &&
(voter == 1 || voter == 2)) {
- test_memeq(rs->identity_digest,
+ tt_mem_op(rs->identity_digest,==,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5",
DIGEST_LEN);
if (voter == 1) {
/* Check the second routerstatus. */
- test_streq(vrs->version, "0.2.0.5");
- test_eq(rs->published_on, now-1000);
- test_streq(rs->nickname, "router1");
+ tt_str_op(vrs->version,==, "0.2.0.5");
+ tt_int_op(rs->published_on,==, now-1000);
+ tt_str_op(rs->nickname,==, "router1");
}
- test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
- test_eq(rs->addr, 0x99009901);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 0);
+ tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
+ tt_int_op(rs->addr,==, 0x99009901);
+ tt_int_op(rs->or_port,==, 443);
+ tt_int_op(rs->dir_port,==, 0);
tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
- test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
- test_eq(rs->ipv6_orport, 4711);
+ tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
+ tt_int_op(rs->ipv6_orport,==, 4711);
if (voter == 1) {
/* all except "authority" (1) and "v2dir" (64) */
tt_u64_op(vrs->flags, ==, U64_LITERAL(190));
@@ -1103,14 +1094,14 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
DIGEST_LEN) &&
(voter == 1 || voter == 2)) {
/* Check the measured bandwidth bits */
- test_assert(vrs->has_measured_bw &&
+ tt_assert(vrs->has_measured_bw &&
vrs->measured_bw_kb == 1024);
} else {
/*
* Didn't expect this, but the old unit test only checked some of them,
* so don't assert.
*/
- /* test_assert(0); */
+ /* tt_assert(0); */
}
done:
@@ -1125,9 +1116,9 @@ test_consensus_for_v3ns(networkstatus_t *con, time_t now)
{
(void)now;
- test_assert(con);
- test_assert(!con->cert);
- test_eq(2, smartlist_len(con->routerstatus_list));
+ tt_assert(con);
+ tt_assert(!con->cert);
+ tt_int_op(2,==, smartlist_len(con->routerstatus_list));
/* There should be two listed routers: one with identity 3, one with
* identity 5. */
@@ -1143,7 +1134,7 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
{
tor_addr_t addr_ipv6;
- test_assert(rs);
+ tt_assert(rs);
/* There should be two listed routers: one with identity 3, one with
* identity 5. */
@@ -1152,49 +1143,49 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
"\x3\x3",
DIGEST_LEN)) {
- test_memeq(rs->identity_digest,
+ tt_mem_op(rs->identity_digest,==,
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
- test_assert(!rs->is_authority);
- test_assert(!rs->is_exit);
- test_assert(!rs->is_fast);
- test_assert(!rs->is_possible_guard);
- test_assert(!rs->is_stable);
+ tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
+ tt_assert(!rs->is_authority);
+ tt_assert(!rs->is_exit);
+ tt_assert(!rs->is_fast);
+ tt_assert(!rs->is_possible_guard);
+ tt_assert(!rs->is_stable);
/* (If it wasn't running it wouldn't be here) */
- test_assert(rs->is_flagged_running);
- test_assert(!rs->is_valid);
- test_assert(!rs->is_named);
+ tt_assert(rs->is_flagged_running);
+ tt_assert(!rs->is_valid);
+ tt_assert(!rs->is_named);
/* XXXX check version */
} else if (tor_memeq(rs->identity_digest,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5",
DIGEST_LEN)) {
/* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
- test_memeq(rs->identity_digest,
+ tt_mem_op(rs->identity_digest,==,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
DIGEST_LEN);
- test_streq(rs->nickname, "router1");
- test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
- test_eq(rs->published_on, now-1000);
- test_eq(rs->addr, 0x99009901);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 0);
+ tt_str_op(rs->nickname,==, "router1");
+ tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
+ tt_int_op(rs->published_on,==, now-1000);
+ tt_int_op(rs->addr,==, 0x99009901);
+ tt_int_op(rs->or_port,==, 443);
+ tt_int_op(rs->dir_port,==, 0);
tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
- test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
- test_eq(rs->ipv6_orport, 4711);
- test_assert(!rs->is_authority);
- test_assert(rs->is_exit);
- test_assert(rs->is_fast);
- test_assert(rs->is_possible_guard);
- test_assert(rs->is_stable);
- test_assert(rs->is_flagged_running);
- test_assert(rs->is_valid);
- test_assert(!rs->is_named);
+ tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
+ tt_int_op(rs->ipv6_orport,==, 4711);
+ tt_assert(!rs->is_authority);
+ tt_assert(rs->is_exit);
+ tt_assert(rs->is_fast);
+ tt_assert(rs->is_possible_guard);
+ tt_assert(rs->is_stable);
+ tt_assert(rs->is_flagged_running);
+ tt_assert(rs->is_valid);
+ tt_assert(!rs->is_named);
/* XXXX check version */
} else {
/* Weren't expecting this... */
- test_assert(0);
+ tt_assert(0);
}
done:
@@ -1242,31 +1233,31 @@ test_a_networkstatus(
networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL;
ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL;
- test_assert(vrs_gen);
- test_assert(rs_test);
- test_assert(vrs_test);
+ tt_assert(vrs_gen);
+ tt_assert(rs_test);
+ tt_assert(vrs_test);
/* Parse certificates and keys. */
cert1 = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
- test_assert(cert1);
+ tt_assert(cert1);
cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL);
- test_assert(cert2);
+ tt_assert(cert2);
cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3, NULL);
- test_assert(cert3);
+ tt_assert(cert3);
sign_skey_1 = crypto_pk_new();
sign_skey_2 = crypto_pk_new();
sign_skey_3 = crypto_pk_new();
sign_skey_leg1 = pk_generate(4);
- test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
+ tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
AUTHORITY_SIGNKEY_1, -1));
- test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
+ tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
AUTHORITY_SIGNKEY_2, -1));
- test_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
+ tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
AUTHORITY_SIGNKEY_3, -1));
- test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
- test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
+ tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
+ tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
/*
* Set up a vote; generate it; try to parse it.
@@ -1308,7 +1299,7 @@ test_a_networkstatus(
vrs = vrs_gen(idx, now);
if (vrs) {
smartlist_add(vote->routerstatus_list, vrs);
- test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs),
+ tt_assert(router_add_to_routerlist(generate_ri_from_rs(vrs),
&msg,0,0)>=0);
++idx;
}
@@ -1317,41 +1308,41 @@ test_a_networkstatus(
/* dump the vote and try to parse it. */
v1_text = format_networkstatus_vote(sign_skey_1, vote);
- test_assert(v1_text);
+ tt_assert(v1_text);
v1 = networkstatus_parse_vote_from_string(v1_text, NULL, NS_TYPE_VOTE);
- test_assert(v1);
+ tt_assert(v1);
/* Make sure the parsed thing was right. */
- test_eq(v1->type, NS_TYPE_VOTE);
- test_eq(v1->published, vote->published);
- test_eq(v1->valid_after, vote->valid_after);
- test_eq(v1->fresh_until, vote->fresh_until);
- test_eq(v1->valid_until, vote->valid_until);
- test_eq(v1->vote_seconds, vote->vote_seconds);
- test_eq(v1->dist_seconds, vote->dist_seconds);
- test_streq(v1->client_versions, vote->client_versions);
- test_streq(v1->server_versions, vote->server_versions);
- test_assert(v1->voters && smartlist_len(v1->voters));
+ tt_int_op(v1->type,==, NS_TYPE_VOTE);
+ tt_int_op(v1->published,==, vote->published);
+ tt_int_op(v1->valid_after,==, vote->valid_after);
+ tt_int_op(v1->fresh_until,==, vote->fresh_until);
+ tt_int_op(v1->valid_until,==, vote->valid_until);
+ tt_int_op(v1->vote_seconds,==, vote->vote_seconds);
+ tt_int_op(v1->dist_seconds,==, vote->dist_seconds);
+ tt_str_op(v1->client_versions,==, vote->client_versions);
+ tt_str_op(v1->server_versions,==, vote->server_versions);
+ tt_assert(v1->voters && smartlist_len(v1->voters));
voter = smartlist_get(v1->voters, 0);
- test_streq(voter->nickname, "Voter1");
- test_streq(voter->address, "1.2.3.4");
- test_eq(voter->addr, 0x01020304);
- test_eq(voter->dir_port, 80);
- test_eq(voter->or_port, 9000);
- test_streq(voter->contact, "voter@example.com");
- test_assert(v1->cert);
- test_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
+ tt_str_op(voter->nickname,==, "Voter1");
+ tt_str_op(voter->address,==, "1.2.3.4");
+ tt_int_op(voter->addr,==, 0x01020304);
+ tt_int_op(voter->dir_port,==, 80);
+ tt_int_op(voter->or_port,==, 9000);
+ tt_str_op(voter->contact,==, "voter@example.com");
+ tt_assert(v1->cert);
+ tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL);
- test_streq(cp, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
+ tt_str_op(cp,==, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid");
tor_free(cp);
- test_eq(smartlist_len(v1->routerstatus_list), n_vrs);
+ tt_int_op(smartlist_len(v1->routerstatus_list),==, n_vrs);
if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now);
/* Check the routerstatuses. */
for (idx = 0; idx < n_vrs; ++idx) {
vrs = smartlist_get(v1->routerstatus_list, idx);
- test_assert(vrs);
+ tt_assert(vrs);
vrs_test(vrs, 1, now);
}
@@ -1381,15 +1372,15 @@ test_a_networkstatus(
/* generate and parse v2. */
v2_text = format_networkstatus_vote(sign_skey_2, vote);
- test_assert(v2_text);
+ tt_assert(v2_text);
v2 = networkstatus_parse_vote_from_string(v2_text, NULL, NS_TYPE_VOTE);
- test_assert(v2);
+ tt_assert(v2);
if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now);
/* Check that flags come out right.*/
cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
- test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
+ tt_str_op(cp,==, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
"Running:Stable:V2Dir:Valid");
tor_free(cp);
@@ -1397,7 +1388,7 @@ test_a_networkstatus(
n_vrs = smartlist_len(v2->routerstatus_list);
for (idx = 0; idx < n_vrs; ++idx) {
vrs = smartlist_get(v2->routerstatus_list, idx);
- test_assert(vrs);
+ tt_assert(vrs);
vrs_test(vrs, 2, now);
}
@@ -1425,10 +1416,10 @@ test_a_networkstatus(
memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN);
v3_text = format_networkstatus_vote(sign_skey_3, vote);
- test_assert(v3_text);
+ tt_assert(v3_text);
v3 = networkstatus_parse_vote_from_string(v3_text, NULL, NS_TYPE_VOTE);
- test_assert(v3);
+ tt_assert(v3);
if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now);
@@ -1442,10 +1433,10 @@ test_a_networkstatus(
"AAAAAAAAAAAAAAAAAAAA",
sign_skey_leg1,
FLAV_NS);
- test_assert(consensus_text);
+ tt_assert(consensus_text);
con = networkstatus_parse_vote_from_string(consensus_text, NULL,
NS_TYPE_CONSENSUS);
- test_assert(con);
+ tt_assert(con);
//log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n",
// v1_text, v2_text, v3_text);
consensus_text_md = networkstatus_compute_consensus(votes, 3,
@@ -1454,38 +1445,38 @@ test_a_networkstatus(
"AAAAAAAAAAAAAAAAAAAA",
sign_skey_leg1,
FLAV_MICRODESC);
- test_assert(consensus_text_md);
+ tt_assert(consensus_text_md);
con_md = networkstatus_parse_vote_from_string(consensus_text_md, NULL,
NS_TYPE_CONSENSUS);
- test_assert(con_md);
- test_eq(con_md->flavor, FLAV_MICRODESC);
+ tt_assert(con_md);
+ tt_int_op(con_md->flavor,==, FLAV_MICRODESC);
/* Check consensus contents. */
- test_assert(con->type == NS_TYPE_CONSENSUS);
- test_eq(con->published, 0); /* this field only appears in votes. */
- test_eq(con->valid_after, now+1000);
- test_eq(con->fresh_until, now+2003); /* median */
- test_eq(con->valid_until, now+3000);
- test_eq(con->vote_seconds, 100);
- test_eq(con->dist_seconds, 250); /* median */
- test_streq(con->client_versions, "0.1.2.14");
- test_streq(con->server_versions, "0.1.2.15,0.1.2.16");
+ tt_assert(con->type == NS_TYPE_CONSENSUS);
+ tt_int_op(con->published,==, 0); /* this field only appears in votes. */
+ tt_int_op(con->valid_after,==, now+1000);
+ tt_int_op(con->fresh_until,==, now+2003); /* median */
+ tt_int_op(con->valid_until,==, now+3000);
+ tt_int_op(con->vote_seconds,==, 100);
+ tt_int_op(con->dist_seconds,==, 250); /* median */
+ tt_str_op(con->client_versions,==, "0.1.2.14");
+ tt_str_op(con->server_versions,==, "0.1.2.15,0.1.2.16");
cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL);
- test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
+ tt_str_op(cp,==, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:"
"Running:Stable:V2Dir:Valid");
tor_free(cp);
if (!params_tweaked) {
/* Skip this one if vote_tweaks() messed with the param lists */
cp = smartlist_join_strings(con->net_params, ":", 0, NULL);
- test_streq(cp, "circuitwindow=80:foo=660");
+ tt_str_op(cp,==, "circuitwindow=80:foo=660");
tor_free(cp);
}
- test_eq(4, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
+ tt_int_op(4,==, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
/* The voter id digests should be in this order. */
- test_assert(memcmp(cert2->cache_info.identity_digest,
+ tt_assert(memcmp(cert2->cache_info.identity_digest,
cert1->cache_info.identity_digest,DIGEST_LEN)<0);
- test_assert(memcmp(cert1->cache_info.identity_digest,
+ tt_assert(memcmp(cert1->cache_info.identity_digest,
cert3->cache_info.identity_digest,DIGEST_LEN)<0);
test_same_voter(smartlist_get(con->voters, 1),
smartlist_get(v2->voters, 0));
@@ -1500,26 +1491,26 @@ test_a_networkstatus(
n_rs = smartlist_len(con->routerstatus_list);
for (idx = 0; idx < n_rs; ++idx) {
rs = smartlist_get(con->routerstatus_list, idx);
- test_assert(rs);
+ tt_assert(rs);
rs_test(rs, now);
}
/* Check signatures. the first voter is a pseudo-entry with a legacy key.
* The second one hasn't signed. The fourth one has signed: validate it. */
voter = smartlist_get(con->voters, 1);
- test_eq(smartlist_len(voter->sigs), 0);
+ tt_int_op(smartlist_len(voter->sigs),==, 0);
voter = smartlist_get(con->voters, 3);
- test_eq(smartlist_len(voter->sigs), 1);
+ tt_int_op(smartlist_len(voter->sigs),==, 1);
sig = smartlist_get(voter->sigs, 0);
- test_assert(sig->signature);
- test_assert(!sig->good_signature);
- test_assert(!sig->bad_signature);
+ tt_assert(sig->signature);
+ tt_assert(!sig->good_signature);
+ tt_assert(!sig->bad_signature);
- test_assert(!networkstatus_check_document_signature(con, sig, cert3));
- test_assert(sig->signature);
- test_assert(sig->good_signature);
- test_assert(!sig->bad_signature);
+ tt_assert(!networkstatus_check_document_signature(con, sig, cert3));
+ tt_assert(sig->signature);
+ tt_assert(sig->good_signature);
+ tt_assert(!sig->bad_signature);
{
const char *msg=NULL;
@@ -1542,10 +1533,10 @@ test_a_networkstatus(
cert1->identity_key,
sign_skey_1, NULL,NULL,
FLAV_MICRODESC);
- test_assert(consensus_text2);
- test_assert(consensus_text3);
- test_assert(consensus_text_md2);
- test_assert(consensus_text_md3);
+ tt_assert(consensus_text2);
+ tt_assert(consensus_text3);
+ tt_assert(consensus_text_md2);
+ tt_assert(consensus_text_md3);
con2 = networkstatus_parse_vote_from_string(consensus_text2, NULL,
NS_TYPE_CONSENSUS);
con3 = networkstatus_parse_vote_from_string(consensus_text3, NULL,
@@ -1554,17 +1545,17 @@ test_a_networkstatus(
NS_TYPE_CONSENSUS);
con_md3 = networkstatus_parse_vote_from_string(consensus_text_md3, NULL,
NS_TYPE_CONSENSUS);
- test_assert(con2);
- test_assert(con3);
- test_assert(con_md2);
- test_assert(con_md3);
+ tt_assert(con2);
+ tt_assert(con3);
+ tt_assert(con_md2);
+ tt_assert(con_md3);
/* All three should have the same digest. */
- test_memeq(&con->digests, &con2->digests, sizeof(digests_t));
- test_memeq(&con->digests, &con3->digests, sizeof(digests_t));
+ tt_mem_op(&con->digests,==, &con2->digests, sizeof(digests_t));
+ tt_mem_op(&con->digests,==, &con3->digests, sizeof(digests_t));
- test_memeq(&con_md->digests, &con_md2->digests, sizeof(digests_t));
- test_memeq(&con_md->digests, &con_md3->digests, sizeof(digests_t));
+ tt_mem_op(&con_md->digests,==, &con_md2->digests, sizeof(digests_t));
+ tt_mem_op(&con_md->digests,==, &con_md3->digests, sizeof(digests_t));
/* Extract a detached signature from con3. */
detached_text1 = get_detached_sigs(con3, con_md3);
@@ -1574,50 +1565,51 @@ test_a_networkstatus(
tt_assert(dsig1);
/* Are parsed values as expected? */
- test_eq(dsig1->valid_after, con3->valid_after);
- test_eq(dsig1->fresh_until, con3->fresh_until);
- test_eq(dsig1->valid_until, con3->valid_until);
+ tt_int_op(dsig1->valid_after,==, con3->valid_after);
+ tt_int_op(dsig1->fresh_until,==, con3->fresh_until);
+ tt_int_op(dsig1->valid_until,==, con3->valid_until);
{
digests_t *dsig_digests = strmap_get(dsig1->digests, "ns");
- test_assert(dsig_digests);
- test_memeq(dsig_digests->d[DIGEST_SHA1], con3->digests.d[DIGEST_SHA1],
+ tt_assert(dsig_digests);
+ tt_mem_op(dsig_digests->d[DIGEST_SHA1],==, con3->digests.d[DIGEST_SHA1],
DIGEST_LEN);
dsig_digests = strmap_get(dsig1->digests, "microdesc");
- test_assert(dsig_digests);
- test_memeq(dsig_digests->d[DIGEST_SHA256],
+ tt_assert(dsig_digests);
+ tt_mem_op(dsig_digests->d[DIGEST_SHA256],==,
con_md3->digests.d[DIGEST_SHA256],
DIGEST256_LEN);
}
{
smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns");
- test_assert(dsig_signatures);
- test_eq(1, smartlist_len(dsig_signatures));
+ tt_assert(dsig_signatures);
+ tt_int_op(1,==, smartlist_len(dsig_signatures));
sig = smartlist_get(dsig_signatures, 0);
- test_memeq(sig->identity_digest, cert1->cache_info.identity_digest,
+ tt_mem_op(sig->identity_digest,==, cert1->cache_info.identity_digest,
DIGEST_LEN);
- test_eq(sig->alg, DIGEST_SHA1);
+ tt_int_op(sig->alg,==, DIGEST_SHA1);
dsig_signatures = strmap_get(dsig1->signatures, "microdesc");
- test_assert(dsig_signatures);
- test_eq(1, smartlist_len(dsig_signatures));
+ tt_assert(dsig_signatures);
+ tt_int_op(1,==, smartlist_len(dsig_signatures));
sig = smartlist_get(dsig_signatures, 0);
- test_memeq(sig->identity_digest, cert1->cache_info.identity_digest,
+ tt_mem_op(sig->identity_digest,==, cert1->cache_info.identity_digest,
DIGEST_LEN);
- test_eq(sig->alg, DIGEST_SHA256);
+ tt_int_op(sig->alg,==, DIGEST_SHA256);
}
/* Try adding it to con2. */
detached_text2 = get_detached_sigs(con2,con_md2);
- test_eq(1, networkstatus_add_detached_signatures(con2, dsig1, "test",
+ tt_int_op(1,==, networkstatus_add_detached_signatures(con2, dsig1, "test",
LOG_INFO, &msg));
tor_free(detached_text2);
- test_eq(1, networkstatus_add_detached_signatures(con_md2, dsig1, "test",
+ tt_int_op(1,==,
+ networkstatus_add_detached_signatures(con_md2, dsig1, "test",
LOG_INFO, &msg));
tor_free(detached_text2);
detached_text2 = get_detached_sigs(con2,con_md2);
//printf("\n<%s>\n", detached_text2);
dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL);
- test_assert(dsig2);
+ tt_assert(dsig2);
/*
printf("\n");
SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, {
@@ -1626,28 +1618,28 @@ test_a_networkstatus(
printf("%s\n", hd);
});
*/
- test_eq(2,
+ tt_int_op(2,==,
smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns")));
- test_eq(2,
+ tt_int_op(2,==,
smartlist_len((smartlist_t*)strmap_get(dsig2->signatures,
"microdesc")));
/* Try adding to con2 twice; verify that nothing changes. */
- test_eq(0, networkstatus_add_detached_signatures(con2, dsig1, "test",
+ tt_int_op(0,==, networkstatus_add_detached_signatures(con2, dsig1, "test",
LOG_INFO, &msg));
/* Add to con. */
- test_eq(2, networkstatus_add_detached_signatures(con, dsig2, "test",
+ tt_int_op(2,==, networkstatus_add_detached_signatures(con, dsig2, "test",
LOG_INFO, &msg));
/* Check signatures */
voter = smartlist_get(con->voters, 1);
sig = smartlist_get(voter->sigs, 0);
- test_assert(sig);
- test_assert(!networkstatus_check_document_signature(con, sig, cert2));
+ tt_assert(sig);
+ tt_assert(!networkstatus_check_document_signature(con, sig, cert2));
voter = smartlist_get(con->voters, 2);
sig = smartlist_get(voter->sigs, 0);
- test_assert(sig);
- test_assert(!networkstatus_check_document_signature(con, sig, cert1));
+ tt_assert(sig);
+ tt_assert(!networkstatus_check_document_signature(con, sig, cert1));
}
done:
@@ -1709,8 +1701,9 @@ test_a_networkstatus(
/** Run unit tests for generating and parsing V3 consensus networkstatus
* documents. */
static void
-test_dir_v3_networkstatus(void)
+test_dir_v3_networkstatus(void *arg)
{
+ (void)arg;
test_a_networkstatus(gen_routerstatus_for_v3ns,
vote_tweaks_for_v3ns,
test_vrs_for_v3ns,
@@ -1749,10 +1742,37 @@ test_dir_scale_bw(void *testdata)
tt_assert(total <= (U64_LITERAL(1)<<62));
for (i=0; i<8; ++i) {
+ /* vals[2].u64 is the scaled value of 1.0 */
double ratio = ((double)vals[i].u64) / vals[2].u64;
tt_double_op(fabs(ratio - v[i]), <, .00001);
}
+ /* test handling of no entries */
+ total = 1;
+ scale_array_elements_to_u64(vals, 0, &total);
+ tt_assert(total == 0);
+
+ /* make sure we don't read the array when we have no entries
+ * may require compiler flags to catch NULL dereferences */
+ total = 1;
+ scale_array_elements_to_u64(NULL, 0, &total);
+ tt_assert(total == 0);
+
+ scale_array_elements_to_u64(NULL, 0, NULL);
+
+ /* test handling of zero totals */
+ total = 1;
+ vals[0].dbl = 0.0;
+ scale_array_elements_to_u64(vals, 1, &total);
+ tt_assert(total == 0);
+ tt_assert(vals[0].u64 == 0);
+
+ vals[0].dbl = 0.0;
+ vals[1].dbl = 0.0;
+ scale_array_elements_to_u64(vals, 2, NULL);
+ tt_assert(vals[0].u64 == 0);
+ tt_assert(vals[1].u64 == 0);
+
done:
;
}
@@ -1958,7 +1978,7 @@ gen_routerstatus_for_umbw(int idx, time_t now)
break;
default:
/* Shouldn't happen */
- test_assert(0);
+ tt_assert(0);
}
if (vrs) {
vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
@@ -1980,11 +2000,11 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
char *maxbw_param = NULL;
int rv = 0;
- test_assert(v);
+ tt_assert(v);
(void)voter;
(void)now;
- test_assert(v->supported_methods);
+ tt_assert(v->supported_methods);
SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c));
smartlist_clear(v->supported_methods);
/* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
@@ -1994,7 +2014,7 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
/* If we're using a non-default clip bandwidth, add it to net_params */
if (alternate_clip_bw > 0) {
tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw);
- test_assert(maxbw_param);
+ tt_assert(maxbw_param);
if (maxbw_param) {
smartlist_add(v->net_params, maxbw_param);
rv = 1;
@@ -2017,9 +2037,9 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
(void)voter;
- test_assert(vrs);
+ tt_assert(vrs);
rs = &(vrs->status);
- test_assert(rs);
+ tt_assert(rs);
/* Split out by digests to test */
if (tor_memeq(rs->identity_digest,
@@ -2030,21 +2050,21 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
* Check the first routerstatus - measured bandwidth below the clip
* cutoff.
*/
- test_streq(vrs->version, "0.1.2.14");
- test_eq(rs->published_on, now-1500);
- test_streq(rs->nickname, "router2");
- test_memeq(rs->identity_digest,
+ tt_str_op(vrs->version,==, "0.1.2.14");
+ tt_int_op(rs->published_on,==, now-1500);
+ tt_str_op(rs->nickname,==, "router2");
+ tt_mem_op(rs->identity_digest,==,
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
- test_eq(rs->addr, 0x99008801);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 8000);
- test_assert(rs->has_bandwidth);
- test_assert(vrs->has_measured_bw);
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2);
- test_eq(vrs->measured_bw_kb, max_unmeasured_bw_kb / 2);
+ tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
+ tt_int_op(rs->addr,==, 0x99008801);
+ tt_int_op(rs->or_port,==, 443);
+ tt_int_op(rs->dir_port,==, 8000);
+ tt_assert(rs->has_bandwidth);
+ tt_assert(vrs->has_measured_bw);
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2);
+ tt_int_op(vrs->measured_bw_kb,==, max_unmeasured_bw_kb / 2);
} else if (tor_memeq(rs->identity_digest,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
@@ -2054,24 +2074,24 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
* Check the second routerstatus - measured bandwidth above the clip
* cutoff.
*/
- test_streq(vrs->version, "0.2.0.5");
- test_eq(rs->published_on, now-1000);
- test_streq(rs->nickname, "router1");
- test_memeq(rs->identity_digest,
+ tt_str_op(vrs->version,==, "0.2.0.5");
+ tt_int_op(rs->published_on,==, now-1000);
+ tt_str_op(rs->nickname,==, "router1");
+ tt_mem_op(rs->identity_digest,==,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
- test_eq(rs->addr, 0x99009901);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 0);
+ tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
+ tt_int_op(rs->addr,==, 0x99009901);
+ tt_int_op(rs->or_port,==, 443);
+ tt_int_op(rs->dir_port,==, 0);
tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
- test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
- test_eq(rs->ipv6_orport, 4711);
- test_assert(rs->has_bandwidth);
- test_assert(vrs->has_measured_bw);
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb * 2);
- test_eq(vrs->measured_bw_kb, max_unmeasured_bw_kb * 2);
+ tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
+ tt_int_op(rs->ipv6_orport,==, 4711);
+ tt_assert(rs->has_bandwidth);
+ tt_assert(vrs->has_measured_bw);
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb * 2);
+ tt_int_op(vrs->measured_bw_kb,==, max_unmeasured_bw_kb * 2);
} else if (tor_memeq(rs->identity_digest,
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
@@ -2081,10 +2101,10 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
* cutoff; this one should be clipped later on in the consensus, but
* appears unclipped in the vote.
*/
- test_assert(rs->has_bandwidth);
- test_assert(!(vrs->has_measured_bw));
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb * 2);
- test_eq(vrs->measured_bw_kb, 0);
+ tt_assert(rs->has_bandwidth);
+ tt_assert(!(vrs->has_measured_bw));
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb * 2);
+ tt_int_op(vrs->measured_bw_kb,==, 0);
} else if (tor_memeq(rs->identity_digest,
"\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
"\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
@@ -2093,12 +2113,12 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
* Check the fourth routerstatus - unmeasured bandwidth below the clip
* cutoff; this one should not be clipped.
*/
- test_assert(rs->has_bandwidth);
- test_assert(!(vrs->has_measured_bw));
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2);
- test_eq(vrs->measured_bw_kb, 0);
+ tt_assert(rs->has_bandwidth);
+ tt_assert(!(vrs->has_measured_bw));
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2);
+ tt_int_op(vrs->measured_bw_kb,==, 0);
} else {
- test_assert(0);
+ tt_assert(0);
}
done:
@@ -2113,11 +2133,11 @@ test_consensus_for_umbw(networkstatus_t *con, time_t now)
{
(void)now;
- test_assert(con);
- test_assert(!con->cert);
- // test_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
- test_assert(con->consensus_method >= 16);
- test_eq(4, smartlist_len(con->routerstatus_list));
+ tt_assert(con);
+ tt_assert(!con->cert);
+ // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB);
+ tt_assert(con->consensus_method >= 16);
+ tt_int_op(4,==, smartlist_len(con->routerstatus_list));
/* There should be four listed routers; all voters saw the same in this */
done:
@@ -2134,61 +2154,61 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ?
alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB;
- test_assert(rs);
+ tt_assert(rs);
/* There should be four listed routers, as constructed above */
if (tor_memeq(rs->identity_digest,
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
DIGEST_LEN)) {
- test_memeq(rs->identity_digest,
+ tt_mem_op(rs->identity_digest,==,
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3"
"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
DIGEST_LEN);
- test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
- test_assert(!rs->is_authority);
- test_assert(!rs->is_exit);
- test_assert(!rs->is_fast);
- test_assert(!rs->is_possible_guard);
- test_assert(!rs->is_stable);
+ tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
+ tt_assert(!rs->is_authority);
+ tt_assert(!rs->is_exit);
+ tt_assert(!rs->is_fast);
+ tt_assert(!rs->is_possible_guard);
+ tt_assert(!rs->is_stable);
/* (If it wasn't running it wouldn't be here) */
- test_assert(rs->is_flagged_running);
- test_assert(!rs->is_valid);
- test_assert(!rs->is_named);
+ tt_assert(rs->is_flagged_running);
+ tt_assert(!rs->is_valid);
+ tt_assert(!rs->is_named);
/* This one should have measured bandwidth below the clip cutoff */
- test_assert(rs->has_bandwidth);
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2);
- test_assert(!(rs->bw_is_unmeasured));
+ tt_assert(rs->has_bandwidth);
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2);
+ tt_assert(!(rs->bw_is_unmeasured));
} else if (tor_memeq(rs->identity_digest,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
DIGEST_LEN)) {
/* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */
- test_memeq(rs->identity_digest,
+ tt_mem_op(rs->identity_digest,==,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
DIGEST_LEN);
- test_streq(rs->nickname, "router1");
- test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
- test_eq(rs->published_on, now-1000);
- test_eq(rs->addr, 0x99009901);
- test_eq(rs->or_port, 443);
- test_eq(rs->dir_port, 0);
+ tt_str_op(rs->nickname,==, "router1");
+ tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
+ tt_int_op(rs->published_on,==, now-1000);
+ tt_int_op(rs->addr,==, 0x99009901);
+ tt_int_op(rs->or_port,==, 443);
+ tt_int_op(rs->dir_port,==, 0);
tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
- test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
- test_eq(rs->ipv6_orport, 4711);
- test_assert(!rs->is_authority);
- test_assert(rs->is_exit);
- test_assert(rs->is_fast);
- test_assert(rs->is_possible_guard);
- test_assert(rs->is_stable);
- test_assert(rs->is_flagged_running);
- test_assert(rs->is_valid);
- test_assert(!rs->is_named);
+ tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
+ tt_int_op(rs->ipv6_orport,==, 4711);
+ tt_assert(!rs->is_authority);
+ tt_assert(rs->is_exit);
+ tt_assert(rs->is_fast);
+ tt_assert(rs->is_possible_guard);
+ tt_assert(rs->is_stable);
+ tt_assert(rs->is_flagged_running);
+ tt_assert(rs->is_valid);
+ tt_assert(!rs->is_named);
/* This one should have measured bandwidth above the clip cutoff */
- test_assert(rs->has_bandwidth);
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb * 2);
- test_assert(!(rs->bw_is_unmeasured));
+ tt_assert(rs->has_bandwidth);
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb * 2);
+ tt_assert(!(rs->bw_is_unmeasured));
} else if (tor_memeq(rs->identity_digest,
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33",
@@ -2197,9 +2217,9 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
* This one should have unmeasured bandwidth above the clip cutoff,
* and so should be clipped
*/
- test_assert(rs->has_bandwidth);
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb);
- test_assert(rs->bw_is_unmeasured);
+ tt_assert(rs->has_bandwidth);
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb);
+ tt_assert(rs->bw_is_unmeasured);
} else if (tor_memeq(rs->identity_digest,
"\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34"
"\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34",
@@ -2208,12 +2228,12 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
* This one should have unmeasured bandwidth below the clip cutoff,
* and so should not be clipped
*/
- test_assert(rs->has_bandwidth);
- test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2);
- test_assert(rs->bw_is_unmeasured);
+ tt_assert(rs->has_bandwidth);
+ tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2);
+ tt_assert(rs->bw_is_unmeasured);
} else {
/* Weren't expecting this... */
- test_assert(0);
+ tt_assert(0);
}
done:
@@ -2227,9 +2247,10 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
*/
static void
-test_dir_clip_unmeasured_bw_kb(void)
+test_dir_clip_unmeasured_bw_kb(void *arg)
{
/* Run the test with the default clip bandwidth */
+ (void)arg;
alternate_clip_bw = 0;
test_a_networkstatus(gen_routerstatus_for_umbw,
vote_tweaks_for_umbw,
@@ -2244,7 +2265,7 @@ test_dir_clip_unmeasured_bw_kb(void)
*/
static void
-test_dir_clip_unmeasured_bw_kb_alt(void)
+test_dir_clip_unmeasured_bw_kb_alt(void *arg)
{
/*
* Try a different one; this value is chosen so that the below-the-cutoff
@@ -2252,6 +2273,7 @@ test_dir_clip_unmeasured_bw_kb_alt(void)
* DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that
* cutoff it will fail the test.
*/
+ (void)arg;
alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB;
test_a_networkstatus(gen_routerstatus_for_umbw,
vote_tweaks_for_umbw,
@@ -2302,60 +2324,60 @@ test_dir_http_handling(void *args)
/* Parse http url tests: */
/* Good headers */
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n"
"Host: example.com\r\n"
"User-Agent: Mozilla/5.0 (Windows;"
" U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
- &url), 0);
- test_streq(url, "/tor/a/b/c.txt");
+ &url),==, 0);
+ tt_str_op(url,==, "/tor/a/b/c.txt");
tor_free(url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url), 0);
- test_streq(url, "/tor/a/b/c.txt");
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),==, 0);
+ tt_str_op(url,==, "/tor/a/b/c.txt");
tor_free(url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url), 0);
- test_streq(url, "/tor/a/b/c.txt");
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),==, 0);
+ tt_str_op(url,==, "/tor/a/b/c.txt");
tor_free(url);
/* Should prepend '/tor/' to url if required */
- test_eq(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
+ tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n"
"Host: example.com\r\n"
"User-Agent: Mozilla/5.0 (Windows;"
" U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
- &url), 0);
- test_streq(url, "/tor/a/b/c.txt");
+ &url),==, 0);
+ tt_str_op(url,==, "/tor/a/b/c.txt");
tor_free(url);
/* Bad headers -- no HTTP/1.x*/
- test_eq(parse_http_url("GET /a/b/c.txt\r\n"
+ tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
"Host: example.com\r\n"
"User-Agent: Mozilla/5.0 (Windows;"
" U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
- &url), -1);
+ &url),==, -1);
tt_assert(!url);
/* Bad headers */
- test_eq(parse_http_url("GET /a/b/c.txt\r\n"
+ tt_int_op(parse_http_url("GET /a/b/c.txt\r\n"
"Host: example.com\r\n"
"User-Agent: Mozilla/5.0 (Windows;"
" U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n",
- &url), -1);
+ &url),==, -1);
tt_assert(!url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt", &url), -1);
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),==, -1);
tt_assert(!url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url), -1);
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),==, -1);
tt_assert(!url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url), -1);
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),==, -1);
tt_assert(!url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url), -1);
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),==, -1);
tt_assert(!url);
- test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url), -1);
+ tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),==, -1);
tt_assert(!url);
done:
@@ -2363,7 +2385,7 @@ test_dir_http_handling(void *args)
}
#define DIR_LEGACY(name) \
- { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_dir_ ## name }
+ { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
#define DIR(name,flags) \
{ #name, test_dir_##name, (flags), NULL, NULL }
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
new file mode 100644
index 0000000000..bddc0f11e0
--- /dev/null
+++ b/src/test/test_entrynodes.c
@@ -0,0 +1,727 @@
+/* Copyright (c) 2014, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+
+#define STATEFILE_PRIVATE
+#define ENTRYNODES_PRIVATE
+#define ROUTERLIST_PRIVATE
+
+#include "or.h"
+#include "test.h"
+#include "entrynodes.h"
+#include "routerparse.h"
+#include "nodelist.h"
+#include "util.h"
+#include "routerlist.h"
+#include "routerset.h"
+#include "statefile.h"
+#include "config.h"
+
+#include "test_descriptors.inc"
+
+/* TODO:
+ * choose_random_entry() test with state set.
+ *
+ * parse_state() tests with more than one guards.
+ *
+ * More tests for set_from_config(): Multiple nodes, use fingerprints,
+ * use country codes.
+ */
+
+/** Dummy Tor state used in unittests. */
+static or_state_t *dummy_state = NULL;
+static or_state_t *
+get_or_state_replacement(void)
+{
+ return dummy_state;
+}
+
+/* NOP replacement for router_descriptor_is_older_than() */
+static int
+router_descriptor_is_older_than_replacement(const routerinfo_t *router,
+ int seconds)
+{
+ (void) router;
+ (void) seconds;
+ return 0;
+}
+
+/* Number of descriptors contained in test_descriptors.txt. */
+#define NUMBER_OF_DESCRIPTORS 8
+
+/** Parse a file containing router descriptors and load them to our
+ routerlist. This function is used to setup an artificial network
+ so that we can conduct entry guard tests. */
+static void
+setup_fake_routerlist(void)
+{
+ int retval;
+ routerlist_t *our_routerlist = NULL;
+ smartlist_t *our_nodelist = NULL;
+
+ /* Read the file that contains our test descriptors. */
+
+ /* We need to mock this function otherwise the descriptors will not
+ accepted as they are too old. */
+ MOCK(router_descriptor_is_older_than,
+ router_descriptor_is_older_than_replacement);
+
+ /* Load all the test descriptors to the routerlist. */
+ retval = router_load_routers_from_string(TEST_DESCRIPTORS,
+ NULL, SAVED_IN_JOURNAL,
+ NULL, 0, NULL);
+ tt_int_op(retval, ==, NUMBER_OF_DESCRIPTORS);
+
+ /* Sanity checking of routerlist and nodelist. */
+ our_routerlist = router_get_routerlist();
+ tt_int_op(smartlist_len(our_routerlist->routers), ==, NUMBER_OF_DESCRIPTORS);
+ routerlist_assert_ok(our_routerlist);
+
+ our_nodelist = nodelist_get_list();
+ tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
+
+ /* Mark all routers as non-guards but up and running! */
+ SMARTLIST_FOREACH_BEGIN(our_nodelist, node_t *, node) {
+ node->is_running = 1;
+ node->is_valid = 1;
+ node->is_possible_guard = 0;
+ } SMARTLIST_FOREACH_END(node);
+
+ done:
+ UNMOCK(router_descriptor_is_older_than);
+}
+
+/* Unittest cleanup function: Cleanup the fake network. */
+static int
+fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ (void) testcase;
+ (void) ptr;
+
+ routerlist_free_all();
+ nodelist_free_all();
+ entry_guards_free_all();
+ or_state_free(dummy_state);
+
+ return 1; /* NOP */
+}
+
+/* Unittest setup function: Setup a fake network. */
+static void *
+fake_network_setup(const struct testcase_t *testcase)
+{
+ (void) testcase;
+
+ /* Setup fake state */
+ dummy_state = tor_malloc_zero(sizeof(or_state_t));
+ MOCK(get_or_state,
+ get_or_state_replacement);
+
+ /* Setup fake routerlist. */
+ setup_fake_routerlist();
+
+ /* Return anything but NULL (it's interpreted as test fail) */
+ return dummy_state;
+}
+
+/** Test choose_random_entry() with none of our routers being guard nodes. */
+static void
+test_choose_random_entry_no_guards(void *arg)
+{
+ const node_t *chosen_entry = NULL;
+
+ (void) arg;
+
+ /* Try to pick an entry even though none of our routers are guards. */
+ chosen_entry = choose_random_entry(NULL);
+
+ /* Unintuitively, we actually pick a random node as our entry,
+ because router_choose_random_node() relaxes its constraints if it
+ can't find a proper entry guard. */
+ tt_assert(chosen_entry);
+
+ done:
+ ;
+}
+
+/** Test choose_random_entry() with only one of our routers being a
+ guard node. */
+static void
+test_choose_random_entry_one_possible_guard(void *arg)
+{
+ const node_t *chosen_entry = NULL;
+ node_t *the_guard = NULL;
+ smartlist_t *our_nodelist = NULL;
+
+ (void) arg;
+
+ /* Set one of the nodes to be a guard. */
+ our_nodelist = nodelist_get_list();
+ the_guard = smartlist_get(our_nodelist, 4); /* chosen by fair dice roll */
+ the_guard->is_possible_guard = 1;
+
+ /* Pick an entry. Make sure we pick the node we marked as guard. */
+ chosen_entry = choose_random_entry(NULL);
+ tt_ptr_op(chosen_entry, ==, the_guard);
+
+ done:
+ ;
+}
+
+/** Helper to conduct tests for populate_live_entry_guards().
+
+ This test adds some entry guards to our list, and then tests
+ populate_live_entry_guards() to mke sure it filters them correctly.
+
+ <b>num_needed</b> is the number of guard nodes we support. It's
+ configurable to make sure we function properly with 1 or 3 guard
+ nodes configured.
+*/
+static void
+populate_live_entry_guards_test_helper(int num_needed)
+{
+ smartlist_t *our_nodelist = NULL;
+ smartlist_t *live_entry_guards = smartlist_new();
+ const smartlist_t *all_entry_guards = get_entry_guards();
+ or_options_t *options = get_options_mutable();
+ int retval;
+
+ /* Set NumEntryGuards to the provided number. */
+ options->NumEntryGuards = num_needed;
+ tt_int_op(num_needed, ==, decide_num_guards(options, 0));
+
+ /* The global entry guards smartlist should be empty now. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, 0);
+
+ /* Walk the nodelist and add all nodes as entry guards. */
+ our_nodelist = nodelist_get_list();
+ tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
+
+ SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
+ const node_t *node_tmp;
+ node_tmp = add_an_entry_guard(node, 0, 1, 0, 0);
+ tt_assert(node_tmp);
+ } SMARTLIST_FOREACH_END(node);
+
+ /* Make sure the nodes were added as entry guards. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, NUMBER_OF_DESCRIPTORS);
+
+ /* Ensure that all the possible entry guards are enough to satisfy us. */
+ tt_int_op(smartlist_len(all_entry_guards), >=, num_needed);
+
+ /* Walk the entry guard list for some sanity checking */
+ SMARTLIST_FOREACH_BEGIN(all_entry_guards, const entry_guard_t *, entry) {
+ /* Since we called add_an_entry_guard() with 'for_discovery' being
+ False, all guards should have made_contact enabled. */
+ tt_int_op(entry->made_contact, ==, 1);
+
+ /* Since we don't have a routerstatus, all of the entry guards are
+ not directory servers. */
+ tt_int_op(entry->is_dir_cache, ==, 0);
+ } SMARTLIST_FOREACH_END(entry);
+
+ /* First, try to get some fast guards. This should fail. */
+ retval = populate_live_entry_guards(live_entry_guards,
+ all_entry_guards,
+ NULL,
+ NO_DIRINFO, /* Don't care about DIRINFO*/
+ 0, 0,
+ 1); /* We want fast guard! */
+ tt_int_op(retval, ==, 0);
+ tt_int_op(smartlist_len(live_entry_guards), ==, 0);
+
+ /* Now try to get some stable guards. This should fail too. */
+ retval = populate_live_entry_guards(live_entry_guards,
+ all_entry_guards,
+ NULL,
+ NO_DIRINFO,
+ 0,
+ 1, /* We want stable guard! */
+ 0);
+ tt_int_op(retval, ==, 0);
+ tt_int_op(smartlist_len(live_entry_guards), ==, 0);
+
+ /* Now try to get any guard we can find. This should succeed. */
+ retval = populate_live_entry_guards(live_entry_guards,
+ all_entry_guards,
+ NULL,
+ NO_DIRINFO,
+ 0, 0, 0); /* No restrictions! */
+
+ /* Since we had more than enough guards in 'all_entry_guards', we
+ should have added 'num_needed' of them to live_entry_guards.
+ 'retval' should be 1 since we now have enough live entry guards
+ to pick one. */
+ tt_int_op(retval, ==, 1);
+ tt_int_op(smartlist_len(live_entry_guards), ==, num_needed);
+
+ done:
+ smartlist_free(live_entry_guards);
+}
+
+/* Test populate_live_entry_guards() for 1 guard node. */
+static void
+test_populate_live_entry_guards_1guard(void *arg)
+{
+ (void) arg;
+
+ populate_live_entry_guards_test_helper(1);
+}
+
+/* Test populate_live_entry_guards() for 3 guard nodes. */
+static void
+test_populate_live_entry_guards_3guards(void *arg)
+{
+ (void) arg;
+
+ populate_live_entry_guards_test_helper(3);
+}
+
+/** Append some EntryGuard lines to the Tor state at <b>state</b>.
+
+ <b>entry_guard_lines</b> is a smartlist containing 2-tuple
+ smartlists that carry the key and values of the statefile.
+ As an example:
+ entry_guard_lines =
+ (("EntryGuard", "name 67E72FF33D7D41BF11C569646A0A7B4B188340DF DirCache"),
+ ("EntryGuardDownSince", "2014-06-07 16:02:46 2014-06-07 16:02:46"))
+*/
+static void
+state_insert_entry_guard_helper(or_state_t *state,
+ smartlist_t *entry_guard_lines)
+{
+ config_line_t **next, *line;
+
+ next = &state->EntryGuards;
+ *next = NULL;
+
+ /* Loop over all the state lines in the smartlist */
+ SMARTLIST_FOREACH_BEGIN(entry_guard_lines, const smartlist_t *,state_lines) {
+ /* Get key and value for each line */
+ const char *state_key = smartlist_get(state_lines, 0);
+ const char *state_value = smartlist_get(state_lines, 1);
+
+ *next = line = tor_malloc_zero(sizeof(config_line_t));
+ line->key = tor_strdup(state_key);
+ tor_asprintf(&line->value, "%s", state_value);
+ next = &(line->next);
+ } SMARTLIST_FOREACH_END(state_lines);
+}
+
+/** Free memory occupied by <b>entry_guard_lines</b>. */
+static void
+state_lines_free(smartlist_t *entry_guard_lines)
+{
+ SMARTLIST_FOREACH_BEGIN(entry_guard_lines, smartlist_t *, state_lines) {
+ char *state_key = smartlist_get(state_lines, 0);
+ char *state_value = smartlist_get(state_lines, 1);
+
+ tor_free(state_key);
+ tor_free(state_value);
+ smartlist_free(state_lines);
+ } SMARTLIST_FOREACH_END(state_lines);
+
+ smartlist_free(entry_guard_lines);
+}
+
+/* Return a statically allocated string representing yesterday's date
+ * in ISO format. We use it so that state file items are not found to
+ * be outdated. */
+static const char *
+get_yesterday_date_str(void)
+{
+ static char buf[ISO_TIME_LEN+1];
+
+ time_t yesterday = time(NULL) - 24*60*60;
+ format_iso_time(buf, yesterday);
+ return buf;
+}
+
+/* Tests entry_guards_parse_state(). It creates a fake Tor state with
+ a saved entry guard and makes sure that Tor can parse it and
+ creates the right entry node out of it.
+*/
+static void
+test_entry_guards_parse_state_simple(void *arg)
+{
+ or_state_t *state = or_state_new();
+ const smartlist_t *all_entry_guards = get_entry_guards();
+ smartlist_t *entry_state_lines = smartlist_new();
+ char *msg = NULL;
+ int retval;
+
+ /* Details of our fake guard node */
+ const char *nickname = "hagbard";
+ const char *fpr = "B29D536DD1752D542E1FBB3C9CE4449D51298212";
+ const char *tor_version = "0.2.5.3-alpha-dev";
+ const char *added_at = get_yesterday_date_str();
+ const char *unlisted_since = "2014-06-08 16:16:50";
+
+ (void) arg;
+
+ /* The global entry guards smartlist should be empty now. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, 0);
+
+ { /* Prepare the state entry */
+
+ /* Prepare the smartlist to hold the key/value of each line */
+ smartlist_t *state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuard");
+ smartlist_add_asprintf(state_line, "%s %s %s", nickname, fpr, "DirCache");
+ smartlist_add(entry_state_lines, state_line);
+
+ state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuardAddedBy");
+ smartlist_add_asprintf(state_line, "%s %s %s", fpr, tor_version, added_at);
+ smartlist_add(entry_state_lines, state_line);
+
+ state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuardUnlistedSince");
+ smartlist_add_asprintf(state_line, "%s", unlisted_since);
+ smartlist_add(entry_state_lines, state_line);
+ }
+
+ /* Inject our lines in the state */
+ state_insert_entry_guard_helper(state, entry_state_lines);
+
+ /* Parse state */
+ retval = entry_guards_parse_state(state, 1, &msg);
+ tt_int_op(retval, >=, 0);
+
+ /* Test that the guard was registered.
+ We need to re-get the entry guard list since its pointer was
+ overwritten in entry_guards_parse_state(). */
+ all_entry_guards = get_entry_guards();
+ tt_int_op(smartlist_len(all_entry_guards), ==, 1);
+
+ { /* Test the entry guard structure */
+ char hex_digest[1024];
+ char str_time[1024];
+
+ const entry_guard_t *e = smartlist_get(all_entry_guards, 0);
+ tt_str_op(e->nickname, ==, nickname); /* Verify nickname */
+
+ base16_encode(hex_digest, sizeof(hex_digest),
+ e->identity, DIGEST_LEN);
+ tt_str_op(hex_digest, ==, fpr); /* Verify fingerprint */
+
+ tt_assert(e->is_dir_cache); /* Verify dirness */
+
+ tt_str_op(e->chosen_by_version, ==, tor_version); /* Verify tor version */
+
+ tt_assert(e->made_contact); /* All saved guards have been contacted */
+
+ tt_assert(e->bad_since); /* Verify bad_since timestamp */
+ format_iso_time(str_time, e->bad_since);
+ tt_str_op(str_time, ==, unlisted_since);
+
+ /* The rest should be unset */
+ tt_assert(!e->unreachable_since);
+ tt_assert(!e->can_retry);
+ tt_assert(!e->path_bias_noticed);
+ tt_assert(!e->path_bias_warned);
+ tt_assert(!e->path_bias_extreme);
+ tt_assert(!e->path_bias_disabled);
+ tt_assert(!e->path_bias_use_noticed);
+ tt_assert(!e->path_bias_use_extreme);
+ tt_assert(!e->last_attempted);
+ }
+
+ done:
+ state_lines_free(entry_state_lines);
+ or_state_free(state);
+ tor_free(msg);
+}
+
+/** Similar to test_entry_guards_parse_state_simple() but aims to test
+ the PathBias-related details of the entry guard. */
+static void
+test_entry_guards_parse_state_pathbias(void *arg)
+{
+ or_state_t *state = or_state_new();
+ const smartlist_t *all_entry_guards = get_entry_guards();
+ char *msg = NULL;
+ int retval;
+ smartlist_t *entry_state_lines = smartlist_new();
+
+ /* Path bias details of the fake guard */
+ const double circ_attempts = 9;
+ const double circ_successes = 8;
+ const double successful_closed = 4;
+ const double collapsed = 2;
+ const double unusable = 0;
+ const double timeouts = 1;
+
+ (void) arg;
+
+ /* The global entry guards smartlist should be empty now. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, 0);
+
+ { /* Prepare the state entry */
+
+ /* Prepare the smartlist to hold the key/value of each line */
+ smartlist_t *state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuard");
+ smartlist_add_asprintf(state_line,
+ "givethanks B29D536DD1752D542E1FBB3C9CE4449D51298212 NoDirCache");
+ smartlist_add(entry_state_lines, state_line);
+
+ state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuardAddedBy");
+ smartlist_add_asprintf(state_line,
+ "B29D536DD1752D542E1FBB3C9CE4449D51298212 0.2.5.3-alpha-dev "
+ "%s", get_yesterday_date_str());
+ smartlist_add(entry_state_lines, state_line);
+
+ state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuardUnlistedSince");
+ smartlist_add_asprintf(state_line, "2014-06-08 16:16:50");
+ smartlist_add(entry_state_lines, state_line);
+
+ state_line = smartlist_new();
+ smartlist_add_asprintf(state_line, "EntryGuardPathBias");
+ smartlist_add_asprintf(state_line, "%f %f %f %f %f %f",
+ circ_attempts, circ_successes, successful_closed,
+ collapsed, unusable, timeouts);
+ smartlist_add(entry_state_lines, state_line);
+ }
+
+ /* Inject our lines in the state */
+ state_insert_entry_guard_helper(state, entry_state_lines);
+
+ /* Parse state */
+ retval = entry_guards_parse_state(state, 1, &msg);
+ tt_int_op(retval, >=, 0);
+
+ /* Test that the guard was registered */
+ all_entry_guards = get_entry_guards();
+ tt_int_op(smartlist_len(all_entry_guards), ==, 1);
+
+ { /* Test the path bias of this guard */
+ const entry_guard_t *e = smartlist_get(all_entry_guards, 0);
+
+ tt_assert(!e->is_dir_cache);
+ tt_assert(!e->can_retry);
+
+ /* XXX tt_double_op doesn't support equality. Cast to int for now. */
+ tt_int_op((int)e->circ_attempts, ==, (int)circ_attempts);
+ tt_int_op((int)e->circ_successes, ==, (int)circ_successes);
+ tt_int_op((int)e->successful_circuits_closed, ==, (int)successful_closed);
+ tt_int_op((int)e->timeouts, ==, (int)timeouts);
+ tt_int_op((int)e->collapsed_circuits, ==, (int)collapsed);
+ tt_int_op((int)e->unusable_circuits, ==, (int)unusable);
+ }
+
+ done:
+ or_state_free(state);
+ state_lines_free(entry_state_lines);
+ tor_free(msg);
+}
+
+/* Simple test of entry_guards_set_from_config() by specifying a
+ particular EntryNode and making sure it gets picked. */
+static void
+test_entry_guards_set_from_config(void *arg)
+{
+ or_options_t *options = get_options_mutable();
+ const smartlist_t *all_entry_guards = get_entry_guards();
+ const char *entrynodes_str = "test003r";
+ const node_t *chosen_entry = NULL;
+ int retval;
+
+ (void) arg;
+
+ /* Prase EntryNodes as a routerset. */
+ options->EntryNodes = routerset_new();
+ retval = routerset_parse(options->EntryNodes,
+ entrynodes_str,
+ "test_entrynodes");
+ tt_int_op(retval, >=, 0);
+
+ /* Read nodes from EntryNodes */
+ entry_guards_set_from_config(options);
+
+ /* Test that only one guard was added. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, 1);
+
+ /* Make sure it was the guard we specified. */
+ chosen_entry = choose_random_entry(NULL);
+ tt_str_op(chosen_entry->ri->nickname, ==, entrynodes_str);
+
+ done:
+ routerset_free(options->EntryNodes);
+}
+
+static void
+test_entry_is_time_to_retry(void *arg)
+{
+ entry_guard_t *test_guard;
+ time_t now;
+ int retval;
+ (void)arg;
+
+ now = time(NULL);
+
+ test_guard = tor_malloc_zero(sizeof(entry_guard_t));
+
+ test_guard->last_attempted = now - 10;
+ test_guard->unreachable_since = now - 1;
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->unreachable_since = now - (6*60*60 - 1);
+ test_guard->last_attempted = now - (60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->last_attempted = now - (60*60 - 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,0);
+
+ test_guard->unreachable_since = now - (6*60*60 + 1);
+ test_guard->last_attempted = now - (4*60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->unreachable_since = now - (3*24*60*60 - 1);
+ test_guard->last_attempted = now - (4*60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->unreachable_since = now - (3*24*60*60 + 1);
+ test_guard->last_attempted = now - (18*60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->unreachable_since = now - (7*24*60*60 - 1);
+ test_guard->last_attempted = now - (18*60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->last_attempted = now - (18*60*60 - 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,0);
+
+ test_guard->unreachable_since = now - (7*24*60*60 + 1);
+ test_guard->last_attempted = now - (36*60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ test_guard->unreachable_since = now - (7*24*60*60 + 1);
+ test_guard->last_attempted = now - (36*60*60 + 1);
+
+ retval = entry_is_time_to_retry(test_guard,now);
+ tt_int_op(retval,==,1);
+
+ done:
+ tor_free(test_guard);
+}
+
+/** XXX Do some tests that entry_is_live() */
+static void
+test_entry_is_live(void *arg)
+{
+ smartlist_t *our_nodelist = NULL;
+ const smartlist_t *all_entry_guards = get_entry_guards();
+ const node_t *test_node = NULL;
+ const entry_guard_t *test_entry = NULL;
+ const char *msg;
+ int which_node;
+
+ (void) arg;
+
+ /* The global entry guards smartlist should be empty now. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, 0);
+
+ /* Walk the nodelist and add all nodes as entry guards. */
+ our_nodelist = nodelist_get_list();
+ tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
+
+ SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
+ const node_t *node_tmp;
+ node_tmp = add_an_entry_guard(node, 0, 1, 0, 0);
+ tt_assert(node_tmp);
+
+ tt_int_op(node->is_stable, ==, 0);
+ tt_int_op(node->is_fast, ==, 0);
+ } SMARTLIST_FOREACH_END(node);
+
+ /* Make sure the nodes were added as entry guards. */
+ tt_int_op(smartlist_len(all_entry_guards), ==, NUMBER_OF_DESCRIPTORS);
+
+ /* Now get a random test entry that we will use for this unit test. */
+ which_node = 3; /* (chosen by fair dice roll) */
+ test_entry = smartlist_get(all_entry_guards, which_node);
+
+ /* Let's do some entry_is_live() tests! */
+
+ /* Require the node to be stable, but it's not. Should fail.
+ Also enable 'assume_reachable' because why not. */
+ test_node = entry_is_live(test_entry,
+ ENTRY_NEED_UPTIME | ENTRY_ASSUME_REACHABLE,
+ &msg);
+ tt_assert(!test_node);
+
+ /* Require the node to be fast, but it's not. Should fail. */
+ test_node = entry_is_live(test_entry,
+ ENTRY_NEED_CAPACITY | ENTRY_ASSUME_REACHABLE,
+ &msg);
+ tt_assert(!test_node);
+
+ /* Don't impose any restrictions on the node. Should succeed. */
+ test_node = entry_is_live(test_entry, 0, &msg);
+ tt_assert(test_node);
+ tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity));
+
+ /* Require descriptor for this node. It has one so it should succeed. */
+ test_node = entry_is_live(test_entry, ENTRY_NEED_DESCRIPTOR, &msg);
+ tt_assert(test_node);
+ tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity));
+
+ done:
+ ; /* XXX */
+}
+
+static const struct testcase_setup_t fake_network = {
+ fake_network_setup, fake_network_cleanup
+};
+
+struct testcase_t entrynodes_tests[] = {
+ { "entry_is_time_to_retry", test_entry_is_time_to_retry,
+ TT_FORK, NULL, NULL },
+ { "choose_random_entry_no_guards", test_choose_random_entry_no_guards,
+ TT_FORK, &fake_network, NULL },
+ { "choose_random_entry_one_possibleguard",
+ test_choose_random_entry_one_possible_guard,
+ TT_FORK, &fake_network, NULL },
+ { "populate_live_entry_guards_1guard",
+ test_populate_live_entry_guards_1guard,
+ TT_FORK, &fake_network, NULL },
+ { "populate_live_entry_guards_3guards",
+ test_populate_live_entry_guards_3guards,
+ TT_FORK, &fake_network, NULL },
+ { "entry_guards_parse_state_simple",
+ test_entry_guards_parse_state_simple,
+ TT_FORK, &fake_network, NULL },
+ { "entry_guards_parse_state_pathbias",
+ test_entry_guards_parse_state_pathbias,
+ TT_FORK, &fake_network, NULL },
+ { "entry_guards_set_from_config",
+ test_entry_guards_set_from_config,
+ TT_FORK, &fake_network, NULL },
+ { "entry_is_live",
+ test_entry_is_live,
+ TT_FORK, &fake_network, NULL },
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c
index 93c8f77d5b..35e7fe5ad9 100644
--- a/src/test/test_extorport.c
+++ b/src/test/test_extorport.c
@@ -42,7 +42,7 @@ test_ext_or_id_map(void *arg)
/* Give c2 a new ID. */
connection_or_set_ext_or_identifier(c2);
- test_mem_op(idp, !=, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
+ tt_mem_op(idp, !=, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
tt_assert(!tor_digest_is_zero(idp2));
@@ -119,7 +119,7 @@ test_ext_or_write_command(void *arg)
==, 0);
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
tt_int_op(sz, ==, 4);
- test_mem_op(cp, ==, "\x00\x99\x00\x00", 4);
+ tt_mem_op(cp, ==, "\x00\x99\x00\x00", 4);
tor_free(cp);
/* Medium command. */
@@ -127,7 +127,7 @@ test_ext_or_write_command(void *arg)
"Wai\0Hello", 9), ==, 0);
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
tt_int_op(sz, ==, 13);
- test_mem_op(cp, ==, "\x00\x99\x00\x09Wai\x00Hello", 13);
+ tt_mem_op(cp, ==, "\x00\x99\x00\x09Wai\x00Hello", 13);
tor_free(cp);
/* Long command */
@@ -137,8 +137,8 @@ test_ext_or_write_command(void *arg)
buf, 65535), ==, 0);
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
tt_int_op(sz, ==, 65539);
- test_mem_op(cp, ==, "\xf0\x0d\xff\xff", 4);
- test_mem_op(cp+4, ==, buf, 65535);
+ tt_mem_op(cp, ==, "\xf0\x0d\xff\xff", 4);
+ tt_mem_op(cp+4, ==, buf, 65535);
tor_free(cp);
done:
@@ -181,7 +181,7 @@ test_ext_or_init_auth(void *arg)
/* Shouldn't be initialized already, or our tests will be a bit
* meaningless */
ext_or_auth_cookie = tor_malloc_zero(32);
- test_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
+ tt_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
/* Now make sure we use a temporary file */
fn = get_fname("ext_cookie_file");
@@ -203,14 +203,14 @@ test_ext_or_init_auth(void *arg)
cp = read_file_to_str(fn, RFTS_BIN, &st);
tt_ptr_op(cp, !=, NULL);
tt_u64_op((uint64_t)st.st_size, ==, 64);
- test_memeq(cp, "! Extended ORPort Auth Cookie !\x0a", 32);
- test_memeq(cp+32, ext_or_auth_cookie, 32);
+ tt_mem_op(cp,==, "! Extended ORPort Auth Cookie !\x0a", 32);
+ tt_mem_op(cp+32,==, ext_or_auth_cookie, 32);
memcpy(cookie0, ext_or_auth_cookie, 32);
- test_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
+ tt_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
/* Operation should be idempotent. */
tt_int_op(0, ==, init_ext_or_cookie_authentication(1));
- test_memeq(cookie0, ext_or_auth_cookie, 32);
+ tt_mem_op(cookie0,==, ext_or_auth_cookie, 32);
done:
tor_free(cp);
@@ -280,15 +280,15 @@ test_ext_or_cookie_auth(void *arg)
46+32+32);
crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
46+32+32);
- test_memeq(hmac1, reply, 32);
- test_memeq(hmac2, client_hash, 32);
+ tt_mem_op(hmac1,==, reply, 32);
+ tt_mem_op(hmac2,==, client_hash, 32);
/* Now do it again and make sure that the results are *different* */
tt_int_op(0, ==,
handle_client_auth_nonce(client_nonce, 32, &client_hash2, &reply2,
&reply_len));
- test_memneq(reply2, reply, reply_len);
- test_memneq(client_hash2, client_hash, 32);
+ tt_mem_op(reply2,!=, reply, reply_len);
+ tt_mem_op(client_hash2,!=, client_hash, 32);
/* But that this one checks out too. */
memcpy(server_hash_input+46+32, reply2+32, 32);
memcpy(client_hash_input+46+32, reply2+32, 32);
@@ -297,8 +297,8 @@ test_ext_or_cookie_auth(void *arg)
46+32+32);
crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
46+32+32);
- test_memeq(hmac1, reply2, 32);
- test_memeq(hmac2, client_hash2, 32);
+ tt_mem_op(hmac1,==, reply2, 32);
+ tt_mem_op(hmac2,==, client_hash2, 32);
done:
tor_free(reply);
@@ -339,7 +339,7 @@ test_ext_or_cookie_auth_testvec(void *arg)
&reply_len));
tt_ptr_op(reply, !=, NULL );
tt_uint_op(reply_len, ==, 64);
- test_memeq(reply+32, "te road There is always another ", 32);
+ tt_mem_op(reply+32,==, "te road There is always another ", 32);
/* HMACSHA256("Gliding wrapt in a brown mantle,"
* "ExtORPort authentication server-to-client hash"
* "But when I look ahead up the write road There is always another ");
@@ -406,7 +406,7 @@ handshake_start(or_connection_t *conn, int receiving)
tt_int_op(buf_datalen(TO_CONN(conn)->outbuf), ==, (n)); \
if ((n)) { \
fetch_from_buf(b, (n), TO_CONN(conn)->outbuf); \
- test_memeq(b, (s), (n)); \
+ tt_mem_op(b, ==, (s), (n)); \
} \
} while (0)
diff --git a/src/test/test_hs.c b/src/test/test_hs.c
index 99ef7dd570..0ee46c2a58 100644
--- a/src/test/test_hs.c
+++ b/src/test/test_hs.c
@@ -84,8 +84,8 @@ test_hs_desc_event(void *arg)
STR_HS_ID);
expected_msg = "650 HS_DESC REQUESTED "STR_HS_ADDR" NO_AUTH "\
STR_HSDIR_EXIST_LONGNAME" "STR_HS_ID"\r\n";
- test_assert(received_msg);
- test_streq(received_msg, expected_msg);
+ tt_assert(received_msg);
+ tt_str_op(received_msg,==, expected_msg);
tor_free(received_msg);
/* test received event */
@@ -93,8 +93,8 @@ test_hs_desc_event(void *arg)
control_event_hs_descriptor_received(&rend_query, HSDIR_EXIST_ID);
expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\
STR_HSDIR_EXIST_LONGNAME"\r\n";
- test_assert(received_msg);
- test_streq(received_msg, expected_msg);
+ tt_assert(received_msg);
+ tt_str_op(received_msg,==, expected_msg);
tor_free(received_msg);
/* test failed event */
@@ -102,8 +102,8 @@ test_hs_desc_event(void *arg)
control_event_hs_descriptor_failed(&rend_query, HSDIR_NONE_EXIST_ID);
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\
STR_HSDIR_NONE_EXIST_LONGNAME"\r\n";
- test_assert(received_msg);
- test_streq(received_msg, expected_msg);
+ tt_assert(received_msg);
+ tt_str_op(received_msg,==, expected_msg);
tor_free(received_msg);
/* test invalid auth type */
@@ -111,8 +111,8 @@ test_hs_desc_event(void *arg)
control_event_hs_descriptor_failed(&rend_query, HSDIR_EXIST_ID);
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\
STR_HSDIR_EXIST_LONGNAME"\r\n";
- test_assert(received_msg);
- test_streq(received_msg, expected_msg);
+ tt_assert(received_msg);
+ tt_str_op(received_msg,==, expected_msg);
tor_free(received_msg);
done:
diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c
index 69c1152229..17ee01d9b8 100644
--- a/src/test/test_introduce.c
+++ b/src/test/test_introduce.c
@@ -290,48 +290,48 @@ do_parse_test(uint8_t *plaintext, size_t plaintext_len, int phase)
/* Get a key */
k = crypto_pk_new();
- test_assert(k);
+ tt_assert(k);
r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_1, -1);
- test_assert(!r);
+ tt_assert(!r);
/* Get digest for future comparison */
r = crypto_pk_get_digest(k, digest);
- test_assert(r >= 0);
+ tt_assert(r >= 0);
/* Make a cell out of it */
r = make_intro_from_plaintext(
plaintext, plaintext_len,
k, (void **)(&cell));
- test_assert(r > 0);
- test_assert(cell);
+ tt_assert(r > 0);
+ tt_assert(cell);
cell_len = r;
/* Do early parsing */
parsed_req = rend_service_begin_parse_intro(cell, cell_len, 2, &err_msg);
- test_assert(parsed_req);
- test_assert(!err_msg);
- test_memeq(parsed_req->pk, digest, DIGEST_LEN);
- test_assert(parsed_req->ciphertext);
- test_assert(parsed_req->ciphertext_len > 0);
+ tt_assert(parsed_req);
+ tt_assert(!err_msg);
+ tt_mem_op(parsed_req->pk,==, digest, DIGEST_LEN);
+ tt_assert(parsed_req->ciphertext);
+ tt_assert(parsed_req->ciphertext_len > 0);
if (phase == EARLY_PARSE_ONLY)
goto done;
/* Do decryption */
r = rend_service_decrypt_intro(parsed_req, k, &err_msg);
- test_assert(!r);
- test_assert(!err_msg);
- test_assert(parsed_req->plaintext);
- test_assert(parsed_req->plaintext_len > 0);
+ tt_assert(!r);
+ tt_assert(!err_msg);
+ tt_assert(parsed_req->plaintext);
+ tt_assert(parsed_req->plaintext_len > 0);
if (phase == DECRYPT_ONLY)
goto done;
/* Do late parsing */
r = rend_service_parse_intro_plaintext(parsed_req, &err_msg);
- test_assert(!r);
- test_assert(!err_msg);
- test_assert(parsed_req->parsed);
+ tt_assert(!r);
+ tt_assert(!err_msg);
+ tt_assert(parsed_req->parsed);
done:
tor_free(cell);
@@ -371,14 +371,14 @@ make_intro_from_plaintext(
/* Compute key digest (will be first DIGEST_LEN octets of cell) */
r = crypto_pk_get_digest(key, cell);
- test_assert(r >= 0);
+ tt_assert(r >= 0);
/* Do encryption */
r = crypto_pk_public_hybrid_encrypt(
key, cell + DIGEST_LEN, ciphertext_size,
buf, len,
PK_PKCS1_OAEP_PADDING, 0);
- test_assert(r >= 0);
+ tt_assert(r >= 0);
/* Figure out cell length */
cell_len = DIGEST_LEN + r;
@@ -394,8 +394,9 @@ make_intro_from_plaintext(
*/
static void
-test_introduce_decrypt_v0(void)
+test_introduce_decrypt_v0(void *arg)
{
+ (void)arg;
do_decrypt_test(v0_test_plaintext, sizeof(v0_test_plaintext));
}
@@ -403,8 +404,9 @@ test_introduce_decrypt_v0(void)
*/
static void
-test_introduce_decrypt_v1(void)
+test_introduce_decrypt_v1(void *arg)
{
+ (void)arg;
do_decrypt_test(v1_test_plaintext, sizeof(v1_test_plaintext));
}
@@ -412,8 +414,9 @@ test_introduce_decrypt_v1(void)
*/
static void
-test_introduce_decrypt_v2(void)
+test_introduce_decrypt_v2(void *arg)
{
+ (void)arg;
do_decrypt_test(v2_test_plaintext, sizeof(v2_test_plaintext));
}
@@ -421,8 +424,9 @@ test_introduce_decrypt_v2(void)
*/
static void
-test_introduce_decrypt_v3(void)
+test_introduce_decrypt_v3(void *arg)
{
+ (void)arg;
do_decrypt_test(
v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext));
do_decrypt_test(
@@ -433,8 +437,9 @@ test_introduce_decrypt_v3(void)
*/
static void
-test_introduce_early_parse_v0(void)
+test_introduce_early_parse_v0(void *arg)
{
+ (void)arg;
do_early_parse_test(v0_test_plaintext, sizeof(v0_test_plaintext));
}
@@ -442,8 +447,9 @@ test_introduce_early_parse_v0(void)
*/
static void
-test_introduce_early_parse_v1(void)
+test_introduce_early_parse_v1(void *arg)
{
+ (void)arg;
do_early_parse_test(v1_test_plaintext, sizeof(v1_test_plaintext));
}
@@ -451,8 +457,9 @@ test_introduce_early_parse_v1(void)
*/
static void
-test_introduce_early_parse_v2(void)
+test_introduce_early_parse_v2(void *arg)
{
+ (void)arg;
do_early_parse_test(v2_test_plaintext, sizeof(v2_test_plaintext));
}
@@ -460,8 +467,9 @@ test_introduce_early_parse_v2(void)
*/
static void
-test_introduce_early_parse_v3(void)
+test_introduce_early_parse_v3(void *arg)
{
+ (void)arg;
do_early_parse_test(
v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext));
do_early_parse_test(
@@ -472,8 +480,9 @@ test_introduce_early_parse_v3(void)
*/
static void
-test_introduce_late_parse_v0(void)
+test_introduce_late_parse_v0(void *arg)
{
+ (void)arg;
do_late_parse_test(v0_test_plaintext, sizeof(v0_test_plaintext));
}
@@ -481,8 +490,9 @@ test_introduce_late_parse_v0(void)
*/
static void
-test_introduce_late_parse_v1(void)
+test_introduce_late_parse_v1(void *arg)
{
+ (void)arg;
do_late_parse_test(v1_test_plaintext, sizeof(v1_test_plaintext));
}
@@ -490,8 +500,9 @@ test_introduce_late_parse_v1(void)
*/
static void
-test_introduce_late_parse_v2(void)
+test_introduce_late_parse_v2(void *arg)
{
+ (void)arg;
do_late_parse_test(v2_test_plaintext, sizeof(v2_test_plaintext));
}
@@ -499,8 +510,9 @@ test_introduce_late_parse_v2(void)
*/
static void
-test_introduce_late_parse_v3(void)
+test_introduce_late_parse_v3(void *arg)
{
+ (void)arg;
do_late_parse_test(
v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext));
do_late_parse_test(
@@ -508,7 +520,7 @@ test_introduce_late_parse_v3(void)
}
#define INTRODUCE_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_introduce_ ## name }
+ { #name, test_introduce_ ## name , 0, NULL, NULL }
struct testcase_t introduce_tests[] = {
INTRODUCE_LEGACY(early_parse_v0),
diff --git a/src/test/test_logging.c b/src/test/test_logging.c
index 7e558f83b1..9f57000bea 100644
--- a/src/test/test_logging.c
+++ b/src/test/test_logging.c
@@ -89,7 +89,7 @@ test_sigsafe_err(void *arg)
init_logging();
mark_logs_temp();
- add_file_log(&include_bug, fn);
+ add_file_log(&include_bug, fn, 0);
tor_log_update_sigsafe_err_fds();
close_temp_logs();
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index 78f4823b87..23e636fbf1 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -108,7 +108,7 @@ test_md_cache(void *data)
md2 = smartlist_get(added, 0);
/* And it should have gotten removed from 'wanted' */
tt_int_op(smartlist_len(wanted), ==, 1);
- test_mem_op(smartlist_get(wanted, 0), ==, d3, DIGEST256_LEN);
+ tt_mem_op(smartlist_get(wanted, 0), ==, d3, DIGEST256_LEN);
smartlist_free(added);
added = NULL;
@@ -144,18 +144,18 @@ test_md_cache(void *data)
tt_int_op(md1->bodylen, ==, strlen(test_md1));
tt_int_op(md2->bodylen, ==, strlen(test_md2));
tt_int_op(md3->bodylen, ==, strlen(test_md3_noannotation));
- test_mem_op(md1->body, ==, test_md1, strlen(test_md1));
- test_mem_op(md2->body, ==, test_md2, strlen(test_md2));
- test_mem_op(md3->body, ==, test_md3_noannotation,
+ tt_mem_op(md1->body, ==, test_md1, strlen(test_md1));
+ tt_mem_op(md2->body, ==, test_md2, strlen(test_md2));
+ tt_mem_op(md3->body, ==, test_md3_noannotation,
strlen(test_md3_noannotation));
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new",
options->DataDirectory);
s = read_file_to_str(fn, RFTS_BIN, NULL);
tt_assert(s);
- test_mem_op(md1->body, ==, s + md1->off, md1->bodylen);
- test_mem_op(md2->body, ==, s + md2->off, md2->bodylen);
- test_mem_op(md3->body, ==, s + md3->off, md3->bodylen);
+ tt_mem_op(md1->body, ==, s + md1->off, md1->bodylen);
+ tt_mem_op(md2->body, ==, s + md2->off, md2->bodylen);
+ tt_mem_op(md3->body, ==, s + md3->off, md3->bodylen);
tt_ptr_op(md1->family, ==, NULL);
tt_ptr_op(md3->family, !=, NULL);
@@ -180,9 +180,9 @@ test_md_cache(void *data)
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
options->DataDirectory);
s = read_file_to_str(fn, RFTS_BIN, NULL);
- test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
- test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
- test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
+ tt_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
+ tt_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
+ tt_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
/* Okay, now we are going to forget about the cache entirely, and reload it
* from the disk. */
@@ -191,12 +191,12 @@ test_md_cache(void *data)
md1 = microdesc_cache_lookup_by_digest256(mc, d1);
md2 = microdesc_cache_lookup_by_digest256(mc, d2);
md3 = microdesc_cache_lookup_by_digest256(mc, d3);
- test_assert(md1);
- test_assert(md2);
- test_assert(md3);
- test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
- test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
- test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
+ tt_assert(md1);
+ tt_assert(md2);
+ tt_assert(md3);
+ tt_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
+ tt_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
+ tt_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
tt_int_op(md1->last_listed, ==, time1);
tt_int_op(md2->last_listed, ==, time2);
diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c
index 600e6a89d4..6d270db960 100644
--- a/src/test/test_nodelist.c
+++ b/src/test/test_nodelist.c
@@ -23,9 +23,9 @@ test_nodelist_node_get_verbose_nickname_by_id_null_node(void *arg)
(void) arg;
/* make sure node_get_by_id returns NULL */
- test_assert(!node_get_by_id(ID));
+ tt_assert(!node_get_by_id(ID));
node_get_verbose_nickname_by_id(ID, vname);
- test_streq(vname, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+ tt_str_op(vname,==, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
done:
return;
}
@@ -54,7 +54,7 @@ test_nodelist_node_get_verbose_nickname_not_named(void *arg)
"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
DIGEST_LEN);
node_get_verbose_nickname(&mock_node, vname);
- test_streq(vname, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
+ tt_str_op(vname,==, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
done:
return;
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index 4cdcd034bb..388251a61f 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -47,17 +47,20 @@ test_policy_summary_helper(const char *policy_str,
line.value = (char *)policy_str;
line.next = NULL;
- r = policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1);
- test_eq(r, 0);
+ r = policies_parse_exit_policy(&line, &policy,
+ EXIT_POLICY_IPV6_ENABLED |
+ EXIT_POLICY_ADD_DEFAULT ,0);
+ tt_int_op(r,==, 0);
+
summary = policy_summarize(policy, AF_INET);
- test_assert(summary != NULL);
- test_streq(summary, expected_summary);
+ tt_assert(summary != NULL);
+ tt_str_op(summary,==, expected_summary);
short_policy = parse_short_policy(summary);
tt_assert(short_policy);
summary_after = write_short_policy(short_policy);
- test_streq(summary, summary_after);
+ tt_str_op(summary,==, summary_after);
done:
tor_free(summary_after);
@@ -86,104 +89,108 @@ test_policies_general(void *arg)
policy = smartlist_new();
p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
- test_assert(p != NULL);
- test_eq(ADDR_POLICY_REJECT, p->policy_type);
+ tt_assert(p != NULL);
+ tt_int_op(ADDR_POLICY_REJECT,==, p->policy_type);
tor_addr_from_ipv4h(&tar, 0xc0a80000u);
- test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
- test_eq(16, p->maskbits);
- test_eq(1, p->prt_min);
- test_eq(65535, p->prt_max);
+ tt_int_op(0,==, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
+ tt_int_op(16,==, p->maskbits);
+ tt_int_op(1,==, p->prt_min);
+ tt_int_op(65535,==, p->prt_max);
smartlist_add(policy, p);
tor_addr_from_ipv4h(&tar, 0x01020304u);
- test_assert(ADDR_POLICY_ACCEPTED ==
+ tt_assert(ADDR_POLICY_ACCEPTED ==
compare_tor_addr_to_addr_policy(&tar, 2, policy));
tor_addr_make_unspec(&tar);
- test_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
+ tt_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
compare_tor_addr_to_addr_policy(&tar, 2, policy));
tor_addr_from_ipv4h(&tar, 0xc0a80102);
- test_assert(ADDR_POLICY_REJECTED ==
+ tt_assert(ADDR_POLICY_REJECTED ==
compare_tor_addr_to_addr_policy(&tar, 2, policy));
- test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, 0, 1));
- test_assert(policy2);
+ tt_int_op(0, ==, policies_parse_exit_policy(NULL, &policy2,
+ EXIT_POLICY_IPV6_ENABLED |
+ EXIT_POLICY_REJECT_PRIVATE |
+ EXIT_POLICY_ADD_DEFAULT, 0));
+
+ tt_assert(policy2);
policy3 = smartlist_new();
p = router_parse_addr_policy_item_from_string("reject *:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy3, p);
p = router_parse_addr_policy_item_from_string("accept *:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy3, p);
policy4 = smartlist_new();
p = router_parse_addr_policy_item_from_string("accept *:443",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy4, p);
p = router_parse_addr_policy_item_from_string("accept *:443",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy4, p);
policy5 = smartlist_new();
p = router_parse_addr_policy_item_from_string("reject 0.0.0.0/8:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject 169.254.0.0/16:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject 127.0.0.0/8:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject 10.0.0.0/8:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject 172.16.0.0/12:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject 80.190.250.90:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject *:1-65534",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("reject *:65535",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
p = router_parse_addr_policy_item_from_string("accept *:1-65535",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy5, p);
policy6 = smartlist_new();
p = router_parse_addr_policy_item_from_string("accept 43.3.0.0/9:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy6, p);
policy7 = smartlist_new();
p = router_parse_addr_policy_item_from_string("accept 0.0.0.0/8:*",-1);
- test_assert(p != NULL);
+ tt_assert(p != NULL);
smartlist_add(policy7, p);
- test_assert(!exit_policy_is_general_exit(policy));
- test_assert(exit_policy_is_general_exit(policy2));
- test_assert(!exit_policy_is_general_exit(NULL));
- test_assert(!exit_policy_is_general_exit(policy3));
- test_assert(!exit_policy_is_general_exit(policy4));
- test_assert(!exit_policy_is_general_exit(policy5));
- test_assert(!exit_policy_is_general_exit(policy6));
- test_assert(!exit_policy_is_general_exit(policy7));
+ tt_assert(!exit_policy_is_general_exit(policy));
+ tt_assert(exit_policy_is_general_exit(policy2));
+ tt_assert(!exit_policy_is_general_exit(NULL));
+ tt_assert(!exit_policy_is_general_exit(policy3));
+ tt_assert(!exit_policy_is_general_exit(policy4));
+ tt_assert(!exit_policy_is_general_exit(policy5));
+ tt_assert(!exit_policy_is_general_exit(policy6));
+ tt_assert(!exit_policy_is_general_exit(policy7));
- test_assert(cmp_addr_policies(policy, policy2));
- test_assert(cmp_addr_policies(policy, NULL));
- test_assert(!cmp_addr_policies(policy2, policy2));
- test_assert(!cmp_addr_policies(NULL, NULL));
+ tt_assert(cmp_addr_policies(policy, policy2));
+ tt_assert(cmp_addr_policies(policy, NULL));
+ tt_assert(!cmp_addr_policies(policy2, policy2));
+ tt_assert(!cmp_addr_policies(NULL, NULL));
- test_assert(!policy_is_reject_star(policy2, AF_INET));
- test_assert(policy_is_reject_star(policy, AF_INET));
- test_assert(policy_is_reject_star(NULL, AF_INET));
+ tt_assert(!policy_is_reject_star(policy2, AF_INET));
+ tt_assert(policy_is_reject_star(policy, AF_INET));
+ tt_assert(policy_is_reject_star(NULL, AF_INET));
addr_policy_list_free(policy);
policy = NULL;
@@ -193,11 +200,14 @@ test_policies_general(void *arg)
line.key = (char*)"foo";
line.value = (char*)"accept *:80,reject private:*,reject *:*";
line.next = NULL;
- test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1));
- test_assert(policy);
+ tt_int_op(0, ==, policies_parse_exit_policy(&line,&policy,
+ EXIT_POLICY_IPV6_ENABLED |
+ EXIT_POLICY_ADD_DEFAULT,0));
+ tt_assert(policy);
+
//test_streq(policy->string, "accept *:80");
//test_streq(policy->next->string, "reject *:*");
- test_eq(smartlist_len(policy), 4);
+ tt_int_op(smartlist_len(policy),==, 4);
/* test policy summaries */
/* check if we properly ignore private IP addresses */
@@ -359,7 +369,7 @@ test_dump_exit_policy_to_string(void *arg)
ri->exit_policy = NULL; // expecting "reject *:*"
ep = router_dump_exit_policy_to_string(ri,1,1);
- test_streq("reject *:*",ep);
+ tt_str_op("reject *:*",==, ep);
tor_free(ep);
@@ -372,7 +382,7 @@ test_dump_exit_policy_to_string(void *arg)
ep = router_dump_exit_policy_to_string(ri,1,1);
- test_streq("accept *:*",ep);
+ tt_str_op("accept *:*",==, ep);
tor_free(ep);
@@ -382,7 +392,7 @@ test_dump_exit_policy_to_string(void *arg)
ep = router_dump_exit_policy_to_string(ri,1,1);
- test_streq("accept *:*\nreject *:25",ep);
+ tt_str_op("accept *:*\nreject *:25",==, ep);
tor_free(ep);
@@ -393,7 +403,7 @@ test_dump_exit_policy_to_string(void *arg)
ep = router_dump_exit_policy_to_string(ri,1,1);
- test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*",ep);
+ tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*",==, ep);
tor_free(ep);
policy_entry =
@@ -403,8 +413,8 @@ test_dump_exit_policy_to_string(void *arg)
ep = router_dump_exit_policy_to_string(ri,1,1);
- test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
- "reject6 [fc00::]/7:*",ep);
+ tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
+ "reject6 [fc00::]/7:*",==, ep);
tor_free(ep);
policy_entry =
@@ -414,8 +424,8 @@ test_dump_exit_policy_to_string(void *arg)
ep = router_dump_exit_policy_to_string(ri,1,1);
- test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
- "reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",ep);
+ tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
+ "reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",==, ep);
done:
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index f71627df1e..61ade84e3a 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -27,75 +27,76 @@ reset_mp(managed_proxy_t *mp)
}
static void
-test_pt_parsing(void)
+test_pt_parsing(void *arg)
{
char line[200];
transport_t *transport = NULL;
tor_addr_t test_addr;
- managed_proxy_t *mp = tor_malloc(sizeof(managed_proxy_t));
+ managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
+ (void)arg;
mp->conf_state = PT_PROTO_INFANT;
mp->transports = smartlist_new();
/* incomplete cmethod */
strlcpy(line,"CMETHOD trebuchet",sizeof(line));
- test_assert(parse_cmethod_line(line, mp) < 0);
+ tt_assert(parse_cmethod_line(line, mp) < 0);
reset_mp(mp);
/* wrong proxy type */
strlcpy(line,"CMETHOD trebuchet dog 127.0.0.1:1999",sizeof(line));
- test_assert(parse_cmethod_line(line, mp) < 0);
+ tt_assert(parse_cmethod_line(line, mp) < 0);
reset_mp(mp);
/* wrong addrport */
strlcpy(line,"CMETHOD trebuchet socks4 abcd",sizeof(line));
- test_assert(parse_cmethod_line(line, mp) < 0);
+ tt_assert(parse_cmethod_line(line, mp) < 0);
reset_mp(mp);
/* correct line */
strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
- test_assert(parse_cmethod_line(line, mp) == 0);
- test_assert(smartlist_len(mp->transports) == 1);
+ tt_assert(parse_cmethod_line(line, mp) == 0);
+ tt_assert(smartlist_len(mp->transports) == 1);
transport = smartlist_get(mp->transports, 0);
/* test registered address of transport */
tor_addr_parse(&test_addr, "127.0.0.1");
- test_assert(tor_addr_eq(&test_addr, &transport->addr));
+ tt_assert(tor_addr_eq(&test_addr, &transport->addr));
/* test registered port of transport */
- test_assert(transport->port == 1999);
+ tt_assert(transport->port == 1999);
/* test registered SOCKS version of transport */
- test_assert(transport->socks_version == PROXY_SOCKS5);
+ tt_assert(transport->socks_version == PROXY_SOCKS5);
/* test registered name of transport */
- test_streq(transport->name, "trebuchet");
+ tt_str_op(transport->name,==, "trebuchet");
reset_mp(mp);
/* incomplete smethod */
strlcpy(line,"SMETHOD trebuchet",sizeof(line));
- test_assert(parse_smethod_line(line, mp) < 0);
+ tt_assert(parse_smethod_line(line, mp) < 0);
reset_mp(mp);
/* wrong addr type */
strlcpy(line,"SMETHOD trebuchet abcd",sizeof(line));
- test_assert(parse_smethod_line(line, mp) < 0);
+ tt_assert(parse_smethod_line(line, mp) < 0);
reset_mp(mp);
/* cowwect */
strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line));
- test_assert(parse_smethod_line(line, mp) == 0);
- test_assert(smartlist_len(mp->transports) == 1);
+ tt_assert(parse_smethod_line(line, mp) == 0);
+ tt_assert(smartlist_len(mp->transports) == 1);
transport = smartlist_get(mp->transports, 0);
/* test registered address of transport */
tor_addr_parse(&test_addr, "127.0.0.2");
- test_assert(tor_addr_eq(&test_addr, &transport->addr));
+ tt_assert(tor_addr_eq(&test_addr, &transport->addr));
/* test registered port of transport */
- test_assert(transport->port == 2999);
+ tt_assert(transport->port == 2999);
/* test registered name of transport */
- test_streq(transport->name, "trebuchy");
+ tt_str_op(transport->name,==, "trebuchy");
reset_mp(mp);
@@ -103,7 +104,7 @@ test_pt_parsing(void)
strlcpy(line,"SMETHOD trebuchet 127.0.0.1:9999 "
"ARGS:counterweight=3,sling=snappy",
sizeof(line));
- test_assert(parse_smethod_line(line, mp) == 0);
+ tt_assert(parse_smethod_line(line, mp) == 0);
tt_int_op(1, ==, smartlist_len(mp->transports));
{
const transport_t *transport = smartlist_get(mp->transports, 0);
@@ -118,15 +119,15 @@ test_pt_parsing(void)
/* unsupported version */
strlcpy(line,"VERSION 666",sizeof(line));
- test_assert(parse_version(line, mp) < 0);
+ tt_assert(parse_version(line, mp) < 0);
/* incomplete VERSION */
strlcpy(line,"VERSION ",sizeof(line));
- test_assert(parse_version(line, mp) < 0);
+ tt_assert(parse_version(line, mp) < 0);
/* correct VERSION */
strlcpy(line,"VERSION 1",sizeof(line));
- test_assert(parse_version(line, mp) == 0);
+ tt_assert(parse_version(line, mp) == 0);
done:
reset_mp(mp);
@@ -187,46 +188,47 @@ test_pt_get_transport_options(void *arg)
}
static void
-test_pt_protocol(void)
+test_pt_protocol(void *arg)
{
char line[200];
managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t));
+ (void)arg;
mp->conf_state = PT_PROTO_LAUNCHED;
mp->transports = smartlist_new();
- mp->argv = tor_malloc_zero(sizeof(char*)*2);
+ mp->argv = tor_calloc(sizeof(char *), 2);
mp->argv[0] = tor_strdup("<testcase>");
/* various wrong protocol runs: */
strlcpy(line,"VERSION 1",sizeof(line));
handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
+ tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
strlcpy(line,"VERSION 1",sizeof(line));
handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_BROKEN);
+ tt_assert(mp->conf_state == PT_PROTO_BROKEN);
reset_mp(mp);
strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_BROKEN);
+ tt_assert(mp->conf_state == PT_PROTO_BROKEN);
reset_mp(mp);
/* correct protocol run: */
strlcpy(line,"VERSION 1",sizeof(line));
handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
+ tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line));
handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
+ tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
strlcpy(line,"CMETHODS DONE",sizeof(line));
handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_CONFIGURED);
+ tt_assert(mp->conf_state == PT_PROTO_CONFIGURED);
done:
reset_mp(mp);
@@ -363,7 +365,7 @@ test_pt_configure_proxy(void *arg)
control_testing_set_global_event_mask(EVENT_TRANSPORT_LAUNCHED);
- mp = tor_malloc(sizeof(managed_proxy_t));
+ mp = tor_malloc_zero(sizeof(managed_proxy_t));
mp->conf_state = PT_PROTO_ACCEPTING_METHODS;
mp->transports = smartlist_new();
mp->transports_to_launch = smartlist_new();
@@ -378,19 +380,19 @@ test_pt_configure_proxy(void *arg)
for (i = 0 ; i < 5 ; i++) {
retval = configure_proxy(mp);
/* retval should be zero because proxy hasn't finished configuring yet */
- test_assert(retval == 0);
+ tt_int_op(retval, ==, 0);
/* check the number of registered transports */
- test_assert(smartlist_len(mp->transports) == i+1);
+ tt_assert(smartlist_len(mp->transports) == i+1);
/* check that the mp is still waiting for transports */
- test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
+ tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
}
/* this last configure_proxy() should finalize the proxy configuration. */
retval = configure_proxy(mp);
/* retval should be 1 since the proxy finished configuring */
- test_assert(retval == 1);
+ tt_int_op(retval, ==, 1);
/* check the mp state */
- test_assert(mp->conf_state == PT_PROTO_COMPLETED);
+ tt_assert(mp->conf_state == PT_PROTO_COMPLETED);
tt_int_op(controlevent_n, ==, 5);
tt_int_op(controlevent_event, ==, EVENT_TRANSPORT_LAUNCHED);
@@ -416,7 +418,7 @@ test_pt_configure_proxy(void *arg)
/* Get the bindaddr for "mock1" and check it against the bindaddr
that the mocked tor_get_lines_from_handle() generated. */
transport_in_state = get_transport_in_state_by_name("mock1");
- test_assert(transport_in_state);
+ tt_assert(transport_in_state);
smartlist_split_string(transport_info_sl, transport_in_state->value,
NULL, 0, 0);
name_of_transport = smartlist_get(transport_info_sl, 0);
@@ -450,8 +452,86 @@ test_pt_configure_proxy(void *arg)
tor_free(mp);
}
+/* Test the get_pt_proxy_uri() function. */
+static void
+test_get_pt_proxy_uri(void *arg)
+{
+ or_options_t *options = get_options_mutable();
+ char *uri = NULL;
+ int ret;
+ (void) arg;
+
+ /* Test with no proxy. */
+ uri = get_pt_proxy_uri();
+ tt_assert(uri == NULL);
+
+ /* Test with a SOCKS4 proxy. */
+ options->Socks4Proxy = tor_strdup("192.0.2.1:1080");
+ ret = tor_addr_port_lookup(options->Socks4Proxy,
+ &options->Socks4ProxyAddr,
+ &options->Socks4ProxyPort);
+ tt_int_op(ret, ==, 0);
+ uri = get_pt_proxy_uri();
+ tt_str_op(uri, ==, "socks4a://192.0.2.1:1080");
+ tor_free(uri);
+ tor_free(options->Socks4Proxy);
+
+ /* Test with a SOCKS5 proxy, no username/password. */
+ options->Socks5Proxy = tor_strdup("192.0.2.1:1080");
+ ret = tor_addr_port_lookup(options->Socks5Proxy,
+ &options->Socks5ProxyAddr,
+ &options->Socks5ProxyPort);
+ tt_int_op(ret, ==, 0);
+ uri = get_pt_proxy_uri();
+ tt_str_op(uri, ==, "socks5://192.0.2.1:1080");
+ tor_free(uri);
+
+ /* Test with a SOCKS5 proxy, with username/password. */
+ options->Socks5ProxyUsername = tor_strdup("hwest");
+ options->Socks5ProxyPassword = tor_strdup("r34n1m470r");
+ uri = get_pt_proxy_uri();
+ tt_str_op(uri, ==, "socks5://hwest:r34n1m470r@192.0.2.1:1080");
+ tor_free(uri);
+ tor_free(options->Socks5Proxy);
+ tor_free(options->Socks5ProxyUsername);
+ tor_free(options->Socks5ProxyPassword);
+
+ /* Test with a HTTPS proxy, no authenticator. */
+ options->HTTPSProxy = tor_strdup("192.0.2.1:80");
+ ret = tor_addr_port_lookup(options->HTTPSProxy,
+ &options->HTTPSProxyAddr,
+ &options->HTTPSProxyPort);
+ tt_int_op(ret, ==, 0);
+ uri = get_pt_proxy_uri();
+ tt_str_op(uri, ==, "http://192.0.2.1:80");
+ tor_free(uri);
+
+ /* Test with a HTTPS proxy, with authenticator. */
+ options->HTTPSProxyAuthenticator = tor_strdup("hwest:r34n1m470r");
+ uri = get_pt_proxy_uri();
+ tt_str_op(uri, ==, "http://hwest:r34n1m470r@192.0.2.1:80");
+ tor_free(uri);
+ tor_free(options->HTTPSProxy);
+ tor_free(options->HTTPSProxyAuthenticator);
+
+ /* Token nod to the fact that IPv6 exists. */
+ options->Socks4Proxy = tor_strdup("[2001:db8::1]:1080");
+ ret = tor_addr_port_lookup(options->Socks4Proxy,
+ &options->Socks4ProxyAddr,
+ &options->Socks4ProxyPort);
+ tt_int_op(ret, ==, 0);
+ uri = get_pt_proxy_uri();
+ tt_str_op(uri, ==, "socks4a://[2001:db8::1]:1080");
+ tor_free(uri);
+ tor_free(options->Socks4Proxy);
+
+ done:
+ if (uri)
+ tor_free(uri);
+}
+
#define PT_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name }
+ { #name, test_pt_ ## name , 0, NULL, NULL }
struct testcase_t pt_tests[] = {
PT_LEGACY(parsing),
@@ -462,6 +542,8 @@ struct testcase_t pt_tests[] = {
NULL, NULL },
{ "configure_proxy",test_pt_configure_proxy, TT_FORK,
NULL, NULL },
+ { "get_pt_proxy_uri", test_get_pt_proxy_uri, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_replay.c b/src/test/test_replay.c
index b48f582f5e..2f543512b0 100644
--- a/src/test/test_replay.c
+++ b/src/test/test_replay.c
@@ -18,12 +18,13 @@ static const char *test_buffer =
" mollit anim id est laborum.";
static void
-test_replaycache_alloc(void)
+test_replaycache_alloc(void *arg)
{
replaycache_t *r = NULL;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
done:
if (r) replaycache_free(r);
@@ -32,21 +33,22 @@ test_replaycache_alloc(void)
}
static void
-test_replaycache_badalloc(void)
+test_replaycache_badalloc(void *arg)
{
replaycache_t *r = NULL;
/* Negative horizon should fail */
+ (void)arg;
r = replaycache_new(-600, 300);
- test_assert(r == NULL);
+ tt_assert(r == NULL);
/* Negative interval should get adjusted to zero */
r = replaycache_new(600, -300);
- test_assert(r != NULL);
- test_eq(r->scrub_interval, 0);
+ tt_assert(r != NULL);
+ tt_int_op(r->scrub_interval,==, 0);
replaycache_free(r);
/* Negative horizon and negative interval should still fail */
r = replaycache_new(-600, -300);
- test_assert(r == NULL);
+ tt_assert(r == NULL);
done:
if (r) replaycache_free(r);
@@ -55,35 +57,37 @@ test_replaycache_badalloc(void)
}
static void
-test_replaycache_free_null(void)
+test_replaycache_free_null(void *arg)
{
+ (void)arg;
replaycache_free(NULL);
/* Assert that we're here without horrible death */
- test_assert(1);
+ tt_assert(1);
done:
return;
}
static void
-test_replaycache_miss(void)
+test_replaycache_miss(void *arg)
{
replaycache_t *r = NULL;
int result;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
result =
replaycache_add_and_test_internal(1200, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
/* poke the bad-parameter error case too */
result =
replaycache_add_and_test_internal(1200, NULL, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
done:
if (r) replaycache_free(r);
@@ -92,23 +96,24 @@ test_replaycache_miss(void)
}
static void
-test_replaycache_hit(void)
+test_replaycache_hit(void *arg)
{
replaycache_t *r = NULL;
int result;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
result =
replaycache_add_and_test_internal(1200, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
result =
replaycache_add_and_test_internal(1300, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
done:
if (r) replaycache_free(r);
@@ -117,28 +122,29 @@ test_replaycache_hit(void)
}
static void
-test_replaycache_age(void)
+test_replaycache_age(void *arg)
{
replaycache_t *r = NULL;
int result;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
result =
replaycache_add_and_test_internal(1200, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
result =
replaycache_add_and_test_internal(1300, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
result =
replaycache_add_and_test_internal(3000, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
done:
if (r) replaycache_free(r);
@@ -147,25 +153,26 @@ test_replaycache_age(void)
}
static void
-test_replaycache_elapsed(void)
+test_replaycache_elapsed(void *arg)
{
replaycache_t *r = NULL;
int result;
time_t elapsed;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
result =
replaycache_add_and_test_internal(1200, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
result =
replaycache_add_and_test_internal(1300, r, test_buffer,
strlen(test_buffer), &elapsed);
- test_eq(result, 1);
- test_eq(elapsed, 100);
+ tt_int_op(result,==, 1);
+ tt_int_op(elapsed,==, 100);
done:
if (r) replaycache_free(r);
@@ -174,28 +181,29 @@ test_replaycache_elapsed(void)
}
static void
-test_replaycache_noexpire(void)
+test_replaycache_noexpire(void *arg)
{
replaycache_t *r = NULL;
int result;
+ (void)arg;
r = replaycache_new(0, 0);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
result =
replaycache_add_and_test_internal(1200, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
result =
replaycache_add_and_test_internal(1300, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
result =
replaycache_add_and_test_internal(3000, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
done:
if (r) replaycache_free(r);
@@ -204,24 +212,25 @@ test_replaycache_noexpire(void)
}
static void
-test_replaycache_scrub(void)
+test_replaycache_scrub(void *arg)
{
replaycache_t *r = NULL;
int result;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
/* Set up like in test_replaycache_hit() */
result =
replaycache_add_and_test_internal(100, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
result =
replaycache_add_and_test_internal(200, r, test_buffer,
strlen(test_buffer), NULL);
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
/*
* Poke a few replaycache_scrub_if_needed_internal() error cases that
@@ -231,12 +240,12 @@ test_replaycache_scrub(void)
/* Null cache */
replaycache_scrub_if_needed_internal(300, NULL);
/* Assert we're still here */
- test_assert(1);
+ tt_assert(1);
/* Make sure we hit the aging-out case too */
replaycache_scrub_if_needed_internal(1500, r);
/* Assert that we aged it */
- test_eq(digestmap_size(r->digests_seen), 0);
+ tt_int_op(digestmap_size(r->digests_seen),==, 0);
done:
if (r) replaycache_free(r);
@@ -245,29 +254,30 @@ test_replaycache_scrub(void)
}
static void
-test_replaycache_future(void)
+test_replaycache_future(void *arg)
{
replaycache_t *r = NULL;
int result;
time_t elapsed = 0;
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
/* Set up like in test_replaycache_hit() */
result =
replaycache_add_and_test_internal(100, r, test_buffer,
strlen(test_buffer), &elapsed);
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
/* elapsed should still be 0, since it wasn't written */
- test_eq(elapsed, 0);
+ tt_int_op(elapsed,==, 0);
result =
replaycache_add_and_test_internal(200, r, test_buffer,
strlen(test_buffer), &elapsed);
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
/* elapsed should be the time since the last hit */
- test_eq(elapsed, 100);
+ tt_int_op(elapsed,==, 100);
/*
* Now let's turn the clock back to get coverage on the cache entry from the
@@ -277,9 +287,9 @@ test_replaycache_future(void)
replaycache_add_and_test_internal(150, r, test_buffer,
strlen(test_buffer), &elapsed);
/* We should still get a hit */
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
/* ...but it shouldn't let us see a negative elapsed time */
- test_eq(elapsed, 0);
+ tt_int_op(elapsed,==, 0);
done:
if (r) replaycache_free(r);
@@ -288,7 +298,7 @@ test_replaycache_future(void)
}
static void
-test_replaycache_realtime(void)
+test_replaycache_realtime(void *arg)
{
replaycache_t *r = NULL;
/*
@@ -299,26 +309,27 @@ test_replaycache_realtime(void)
int result;
/* Test the realtime as well as *_internal() entry points */
+ (void)arg;
r = replaycache_new(600, 300);
- test_assert(r != NULL);
+ tt_assert(r != NULL);
/* This should miss */
result =
replaycache_add_and_test(r, test_buffer, strlen(test_buffer));
- test_eq(result, 0);
+ tt_int_op(result,==, 0);
/* This should hit */
result =
replaycache_add_and_test(r, test_buffer, strlen(test_buffer));
- test_eq(result, 1);
+ tt_int_op(result,==, 1);
/* This should hit and return a small elapsed time */
result =
replaycache_add_test_and_elapsed(r, test_buffer,
strlen(test_buffer), &elapsed);
- test_eq(result, 1);
- test_assert(elapsed >= 0);
- test_assert(elapsed <= 5);
+ tt_int_op(result,==, 1);
+ tt_assert(elapsed >= 0);
+ tt_assert(elapsed <= 5);
/* Scrub it to exercise that entry point too */
replaycache_scrub_if_needed(r);
@@ -329,7 +340,7 @@ test_replaycache_realtime(void)
}
#define REPLAYCACHE_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_replaycache_ ## name }
+ { #name, test_replaycache_ ## name , 0, NULL, NULL }
struct testcase_t replaycache_tests[] = {
REPLAYCACHE_LEGACY(alloc),
diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c
new file mode 100644
index 0000000000..81e4dbb1eb
--- /dev/null
+++ b/src/test/test_routerset.c
@@ -0,0 +1,2122 @@
+#define ROUTERSET_PRIVATE
+
+#include "or.h"
+#include "geoip.h"
+#include "routerset.h"
+#include "routerparse.h"
+#include "policies.h"
+#include "nodelist.h"
+#include "test.h"
+
+#define NS_MODULE routerset
+
+#define NS_SUBMODULE routerset_new
+
+/*
+ * Functional (blackbox) test to determine that each member of the routerset
+ * is non-NULL
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *rs;
+ (void)arg;
+
+ rs = routerset_new();
+
+ tt_ptr_op(rs, !=, NULL);
+ tt_ptr_op(rs->list, !=, NULL);
+ tt_ptr_op(rs->names, !=, NULL);
+ tt_ptr_op(rs->digests, !=, NULL);
+ tt_ptr_op(rs->policies, !=, NULL);
+ tt_ptr_op(rs->country_names, !=, NULL);
+
+ done:
+ routerset_free(rs);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_get_countryname
+
+/*
+ * Functional test to strip the braces from a "{xx}" country code string.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ const char *input;
+ char *name;
+ (void)arg;
+
+ /* strlen(c) < 4 */
+ input = "xxx";
+ name = routerset_get_countryname(input);
+ tt_ptr_op(name, ==, NULL);
+ tor_free(name);
+
+ /* c[0] != '{' */
+ input = "xxx}";
+ name = routerset_get_countryname(input);
+ tt_ptr_op(name, ==, NULL);
+ tor_free(name);
+
+ /* c[3] != '}' */
+ input = "{xxx";
+ name = routerset_get_countryname(input);
+ tt_ptr_op(name, ==, NULL);
+ tor_free(name);
+
+ /* tor_strlower */
+ input = "{XX}";
+ name = routerset_get_countryname(input);
+ tt_str_op(name, ==, "xx");
+ tor_free(name);
+
+ input = "{xx}";
+ name = routerset_get_countryname(input);
+ tt_str_op(name, ==, "xx");
+ done:
+ tor_free(name);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_refresh_counties, geoip_not_loaded)
+
+/*
+ * Structural (whitebox) test for routerset_refresh_counties, when the GeoIP DB
+ * is not loaded.
+ */
+
+NS_DECL(int, geoip_is_loaded, (sa_family_t family));
+NS_DECL(int, geoip_get_n_countries, (void));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ (void)arg;
+
+ NS_MOCK(geoip_is_loaded);
+ NS_MOCK(geoip_get_n_countries);
+
+ routerset_refresh_countries(set);
+
+ tt_ptr_op(set->countries, ==, NULL);
+ tt_int_op(set->n_countries, ==, 0);
+ tt_int_op(CALLED(geoip_is_loaded), ==, 1);
+ tt_int_op(CALLED(geoip_get_n_countries), ==, 0);
+
+ done:
+ NS_UNMOCK(geoip_is_loaded);
+ NS_UNMOCK(geoip_get_n_countries);
+ routerset_free(set);
+}
+
+static int
+NS(geoip_is_loaded)(sa_family_t family)
+{
+ (void)family;
+ CALLED(geoip_is_loaded)++;
+
+ return 0;
+}
+
+static int
+NS(geoip_get_n_countries)(void)
+{
+ CALLED(geoip_get_n_countries)++;
+
+ return 0;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_refresh_counties, no_countries)
+
+/*
+ * Structural test for routerset_refresh_counties, when there are no countries.
+ */
+
+NS_DECL(int, geoip_is_loaded, (sa_family_t family));
+NS_DECL(int, geoip_get_n_countries, (void));
+NS_DECL(country_t, geoip_get_country, (const char *country));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ (void)arg;
+
+ NS_MOCK(geoip_is_loaded);
+ NS_MOCK(geoip_get_n_countries);
+ NS_MOCK(geoip_get_country);
+
+ routerset_refresh_countries(set);
+
+ tt_ptr_op(set->countries, !=, NULL);
+ tt_int_op(set->n_countries, ==, 1);
+ tt_int_op((unsigned int)(*set->countries), ==, 0);
+ tt_int_op(CALLED(geoip_is_loaded), ==, 1);
+ tt_int_op(CALLED(geoip_get_n_countries), ==, 1);
+ tt_int_op(CALLED(geoip_get_country), ==, 0);
+
+ done:
+ NS_UNMOCK(geoip_is_loaded);
+ NS_UNMOCK(geoip_get_n_countries);
+ NS_UNMOCK(geoip_get_country);
+ routerset_free(set);
+}
+
+static int
+NS(geoip_is_loaded)(sa_family_t family)
+{
+ (void)family;
+ CALLED(geoip_is_loaded)++;
+
+ return 1;
+}
+
+static int
+NS(geoip_get_n_countries)(void)
+{
+ CALLED(geoip_get_n_countries)++;
+
+ return 1;
+}
+
+static country_t
+NS(geoip_get_country)(const char *countrycode)
+{
+ (void)countrycode;
+ CALLED(geoip_get_country)++;
+
+ return 1;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_refresh_counties, one_valid_country)
+
+/*
+ * Structural test for routerset_refresh_counties, with one valid country.
+ */
+
+NS_DECL(int, geoip_is_loaded, (sa_family_t family));
+NS_DECL(int, geoip_get_n_countries, (void));
+NS_DECL(country_t, geoip_get_country, (const char *country));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ (void)arg;
+
+ NS_MOCK(geoip_is_loaded);
+ NS_MOCK(geoip_get_n_countries);
+ NS_MOCK(geoip_get_country);
+ smartlist_add(set->country_names, tor_strndup("foo", 3));
+
+ routerset_refresh_countries(set);
+
+ tt_ptr_op(set->countries, !=, NULL);
+ tt_int_op(set->n_countries, ==, 2);
+ tt_int_op(CALLED(geoip_is_loaded), ==, 1);
+ tt_int_op(CALLED(geoip_get_n_countries), ==, 1);
+ tt_int_op(CALLED(geoip_get_country), ==, 1);
+ tt_int_op((unsigned int)(*set->countries), !=, 0);
+
+ done:
+ NS_UNMOCK(geoip_is_loaded);
+ NS_UNMOCK(geoip_get_n_countries);
+ NS_UNMOCK(geoip_get_country);
+ routerset_free(set);
+}
+
+static int
+NS(geoip_is_loaded)(sa_family_t family)
+{
+ (void)family;
+ CALLED(geoip_is_loaded)++;
+
+ return 1;
+}
+
+static int
+NS(geoip_get_n_countries)(void)
+{
+ CALLED(geoip_get_n_countries)++;
+
+ return 2;
+}
+
+static country_t
+NS(geoip_get_country)(const char *countrycode)
+{
+ (void)countrycode;
+ CALLED(geoip_get_country)++;
+
+ return 1;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_refresh_counties, one_invalid_country)
+
+/*
+ * Structural test for routerset_refresh_counties, with one invalid
+ * country code..
+ */
+
+NS_DECL(int, geoip_is_loaded, (sa_family_t family));
+NS_DECL(int, geoip_get_n_countries, (void));
+NS_DECL(country_t, geoip_get_country, (const char *country));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ (void)arg;
+
+ NS_MOCK(geoip_is_loaded);
+ NS_MOCK(geoip_get_n_countries);
+ NS_MOCK(geoip_get_country);
+ smartlist_add(set->country_names, tor_strndup("foo", 3));
+
+ routerset_refresh_countries(set);
+
+ tt_ptr_op(set->countries, !=, NULL);
+ tt_int_op(set->n_countries, ==, 2);
+ tt_int_op(CALLED(geoip_is_loaded), ==, 1);
+ tt_int_op(CALLED(geoip_get_n_countries), ==, 1);
+ tt_int_op(CALLED(geoip_get_country), ==, 1);
+ tt_int_op((unsigned int)(*set->countries), ==, 0);
+
+ done:
+ NS_UNMOCK(geoip_is_loaded);
+ NS_UNMOCK(geoip_get_n_countries);
+ NS_UNMOCK(geoip_get_country);
+ routerset_free(set);
+}
+
+static int
+NS(geoip_is_loaded)(sa_family_t family)
+{
+ (void)family;
+ CALLED(geoip_is_loaded)++;
+
+ return 1;
+}
+
+static int
+NS(geoip_get_n_countries)(void)
+{
+ CALLED(geoip_get_n_countries)++;
+
+ return 2;
+}
+
+static country_t
+NS(geoip_get_country)(const char *countrycode)
+{
+ (void)countrycode;
+ CALLED(geoip_get_country)++;
+
+ return -1;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_parse, malformed)
+
+/*
+ * Functional test, with a malformed string to parse.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ const char *s = "_";
+ int r;
+ (void)arg;
+
+ r = routerset_parse(set, s, "");
+
+ tt_int_op(r, ==, -1);
+
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_parse, valid_hexdigest)
+
+/*
+ * Functional test for routerset_parse, that routerset_parse returns 0
+ * on a valid hexdigest entry.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set;
+ const char *s;
+ int r;
+ (void)arg;
+
+ set = routerset_new();
+ s = "$0000000000000000000000000000000000000000";
+ r = routerset_parse(set, s, "");
+ tt_int_op(r, ==, 0);
+ tt_int_op(digestmap_isempty(set->digests), !=, 1);
+
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_parse, valid_nickname)
+
+/*
+ * Functional test for routerset_parse, when given a valid nickname as input.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set;
+ const char *s;
+ int r;
+ (void)arg;
+
+ set = routerset_new();
+ s = "fred";
+ r = routerset_parse(set, s, "");
+ tt_int_op(r, ==, 0);
+ tt_int_op(strmap_isempty(set->names), !=, 1);
+
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_parse, get_countryname)
+
+/*
+ * Functional test for routerset_parse, when given a valid countryname.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set;
+ const char *s;
+ int r;
+ (void)arg;
+
+ set = routerset_new();
+ s = "{cc}";
+ r = routerset_parse(set, s, "");
+ tt_int_op(r, ==, 0);
+ tt_int_op(smartlist_len(set->country_names), !=, 0);
+
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_parse, policy)
+
+/*
+ * Structural test for routerset_parse, when given a valid policy.
+ */
+
+NS_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string,
+ (const char *s, int assume_action));
+
+addr_policy_t *NS(mock_addr_policy);
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set;
+ const char *s;
+ int r;
+ (void)arg;
+
+ NS_MOCK(router_parse_addr_policy_item_from_string);
+ NS(mock_addr_policy) = tor_malloc_zero(sizeof(addr_policy_t));
+
+ set = routerset_new();
+ s = "*";
+ r = routerset_parse(set, s, "");
+ tt_int_op(r, ==, 0);
+ tt_int_op(smartlist_len(set->policies), !=, 0);
+ tt_int_op(CALLED(router_parse_addr_policy_item_from_string), ==, 1);
+
+ done:
+ routerset_free(set);
+}
+
+addr_policy_t *
+NS(router_parse_addr_policy_item_from_string)(const char *s, int assume_action)
+{
+ (void)s;
+ (void)assume_action;
+ CALLED(router_parse_addr_policy_item_from_string)++;
+
+ return NS(mock_addr_policy);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_union, source_bad)
+
+/*
+ * Structural test for routerset_union, when given a bad source argument.
+ */
+
+NS_DECL(smartlist_t *, smartlist_new, (void));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set, *bad_set;
+ (void)arg;
+
+ set = routerset_new();
+ bad_set = routerset_new();
+ smartlist_free(bad_set->list);
+ bad_set->list = NULL;
+
+ NS_MOCK(smartlist_new);
+
+ routerset_union(set, NULL);
+ tt_int_op(CALLED(smartlist_new), ==, 0);
+
+ routerset_union(set, bad_set);
+ tt_int_op(CALLED(smartlist_new), ==, 0);
+
+ done:
+ NS_UNMOCK(smartlist_new);
+ routerset_free(set);
+
+ /* Just recreate list, so we can simply use routerset_free. */
+ bad_set->list = smartlist_new();
+ routerset_free(bad_set);
+}
+
+static smartlist_t *
+NS(smartlist_new)(void)
+{
+ CALLED(smartlist_new)++;
+
+ return NULL;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_union, one)
+
+/*
+ * Functional test for routerset_union.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *src = routerset_new();
+ routerset_t *tgt;
+ (void)arg;
+
+ tgt = routerset_new();
+ smartlist_add(src->list, tor_strdup("{xx}"));
+ routerset_union(tgt, src);
+
+ tt_int_op(smartlist_len(tgt->list), !=, 0);
+
+ done:
+ routerset_free(src);
+ routerset_free(tgt);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_is_list
+
+/*
+ * Functional tests for routerset_is_list.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set;
+ addr_policy_t *policy;
+ int is_list;
+ (void)arg;
+
+ /* len(set->country_names) == 0, len(set->policies) == 0 */
+ set = routerset_new();
+ is_list = routerset_is_list(set);
+ routerset_free(set);
+ set = NULL;
+ tt_int_op(is_list, !=, 0);
+
+ /* len(set->country_names) != 0, len(set->policies) == 0 */
+ set = routerset_new();
+ smartlist_add(set->country_names, tor_strndup("foo", 3));
+ is_list = routerset_is_list(set);
+ routerset_free(set);
+ set = NULL;
+ tt_int_op(is_list, ==, 0);
+
+ /* len(set->country_names) == 0, len(set->policies) != 0 */
+ set = routerset_new();
+ policy = tor_malloc_zero(sizeof(addr_policy_t));
+ smartlist_add(set->policies, (void *)policy);
+ is_list = routerset_is_list(set);
+ routerset_free(set);
+ set = NULL;
+ tt_int_op(is_list, ==, 0);
+
+ /* len(set->country_names) != 0, len(set->policies) != 0 */
+ set = routerset_new();
+ smartlist_add(set->country_names, tor_strndup("foo", 3));
+ policy = tor_malloc_zero(sizeof(addr_policy_t));
+ smartlist_add(set->policies, (void *)policy);
+ is_list = routerset_is_list(set);
+ routerset_free(set);
+ set = NULL;
+ tt_int_op(is_list, ==, 0);
+
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_needs_geoip
+
+/*
+ * Functional tests for routerset_needs_geoip.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ const routerset_t *set;
+ int needs_geoip;
+ (void)arg;
+
+ set = NULL;
+ needs_geoip = routerset_needs_geoip(set);
+ tt_int_op(needs_geoip, ==, 0);
+
+ set = routerset_new();
+ needs_geoip = routerset_needs_geoip(set);
+ routerset_free((routerset_t *)set);
+ tt_int_op(needs_geoip, ==, 0);
+ set = NULL;
+
+ set = routerset_new();
+ smartlist_add(set->country_names, tor_strndup("xx", 2));
+ needs_geoip = routerset_needs_geoip(set);
+ routerset_free((routerset_t *)set);
+ set = NULL;
+ tt_int_op(needs_geoip, !=, 0);
+
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_is_empty
+
+/*
+ * Functional tests for routerset_is_empty.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = NULL;
+ int is_empty;
+ (void)arg;
+
+ is_empty = routerset_is_empty(set);
+ tt_int_op(is_empty, !=, 0);
+
+ set = routerset_new();
+ is_empty = routerset_is_empty(set);
+ routerset_free(set);
+ set = NULL;
+ tt_int_op(is_empty, !=, 0);
+
+ set = routerset_new();
+ smartlist_add(set->list, tor_strdup("{xx}"));
+ is_empty = routerset_is_empty(set);
+ routerset_free(set);
+ set = NULL;
+ tt_int_op(is_empty, ==, 0);
+
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, null_set_or_null_set_list)
+
+/*
+ * Functional test for routerset_contains, when given a NULL set or the
+ * set has a NULL list.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = NULL;
+ int contains;
+ (void)arg;
+
+ contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
+
+ tt_int_op(contains, ==, 0);
+
+ set = tor_malloc_zero(sizeof(routerset_t));
+ set->list = NULL;
+ contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
+ tor_free(set);
+ tt_int_op(contains, ==, 0);
+
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_null_nickname)
+
+/*
+ * Functional test for routerset_contains, when given a valid routerset but a
+ * NULL nickname.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ char *nickname = NULL;
+ int contains;
+ (void)arg;
+
+ contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 0);
+
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_nickname)
+
+/*
+ * Functional test for routerset_contains, when given a valid routerset
+ * and the nickname is in the routerset.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ const char *nickname;
+ int contains;
+ (void)arg;
+
+ nickname = "Foo"; /* This tests the lowercase comparison as well. */
+ strmap_set_lc(set->names, nickname, (void *)1);
+ contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 4);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_no_nickname)
+
+/*
+ * Functional test for routerset_contains, when given a valid routerset
+ * and the nickname is not in the routerset.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains;
+ (void)arg;
+
+ strmap_set_lc(set->names, "bar", (void *)1);
+ contains = routerset_contains(set, NULL, 0, "foo", NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 0);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_digest)
+
+/*
+ * Functional test for routerset_contains, when given a valid routerset
+ * and the digest is contained in the routerset.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains;
+ uint8_t foo[20] = { 2, 3, 4 };
+ (void)arg;
+
+ digestmap_set(set->digests, (const char*)foo, (void *)1);
+ contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 4);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_no_digest)
+
+/*
+ * Functional test for routerset_contains, when given a valid routerset
+ * and the digest is not contained in the routerset.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains;
+ uint8_t bar[20] = { 9, 10, 11, 55 };
+ uint8_t foo[20] = { 1, 2, 3, 4};
+ (void)arg;
+
+ digestmap_set(set->digests, (const char*)bar, (void *)1);
+ contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 0);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_null_digest)
+
+/*
+ * Functional test for routerset_contains, when given a valid routerset
+ * and the digest is NULL.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains;
+ uint8_t bar[20] = { 9, 10, 11, 55 };
+ (void)arg;
+
+ digestmap_set(set->digests, (const char*)bar, (void *)1);
+ contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 0);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_addr)
+
+/*
+ * Structural test for routerset_contains, when given a valid routerset
+ * and the address is rejected by policy.
+ */
+
+NS_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
+ (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
+
+static tor_addr_t MOCK_TOR_ADDR;
+#define MOCK_TOR_ADDR_PTR (&MOCK_TOR_ADDR)
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ tor_addr_t *addr = MOCK_TOR_ADDR_PTR;
+ int contains;
+ (void)arg;
+
+ NS_MOCK(compare_tor_addr_to_addr_policy);
+
+ contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
+ tt_int_op(contains, ==, 3);
+
+ done:
+ ;
+}
+
+addr_policy_result_t
+NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
+ const smartlist_t *policy)
+{
+ (void)port;
+ (void)policy;
+ CALLED(compare_tor_addr_to_addr_policy)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+ return ADDR_POLICY_REJECTED;
+
+ done:
+ return 0;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_no_addr)
+
+/*
+ * Structural test for routerset_contains, when given a valid routerset
+ * and the address is not rejected by policy.
+ */
+
+NS_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
+ (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ tor_addr_t *addr = MOCK_TOR_ADDR_PTR;
+ int contains;
+ (void)arg;
+
+ NS_MOCK(compare_tor_addr_to_addr_policy);
+
+ contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
+ tt_int_op(contains, ==, 0);
+
+ done:
+ ;
+}
+
+addr_policy_result_t
+NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
+ const smartlist_t *policy)
+{
+ (void)port;
+ (void)policy;
+ CALLED(compare_tor_addr_to_addr_policy)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+
+ return ADDR_POLICY_ACCEPTED;
+
+ done:
+ return 0;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, set_and_null_addr)
+
+/*
+ * Structural test for routerset_contains, when given a valid routerset
+ * and the address is NULL.
+ */
+
+NS_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
+ (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains;
+ (void)arg;
+
+ NS_MOCK(compare_tor_addr_to_addr_policy);
+
+ contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 0);
+
+ done:
+ ;
+}
+
+addr_policy_result_t
+NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
+ const smartlist_t *policy)
+{
+ (void)port;
+ (void)policy;
+ CALLED(compare_tor_addr_to_addr_policy)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+
+ return ADDR_POLICY_ACCEPTED;
+
+ done:
+ return 0;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, countries_no_geoip)
+
+/*
+ * Structural test for routerset_contains, when there is no matching country
+ * for the address.
+ */
+
+NS_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
+ (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
+NS_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains = 1;
+ (void)arg;
+
+ NS_MOCK(compare_tor_addr_to_addr_policy);
+ NS_MOCK(geoip_get_country_by_addr);
+
+ set->countries = bitarray_init_zero(1);
+ bitarray_set(set->countries, 1);
+ contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 0);
+ tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
+ tt_int_op(CALLED(geoip_get_country_by_addr), ==, 1);
+
+ done:
+ ;
+}
+
+addr_policy_result_t
+NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
+ const smartlist_t *policy)
+{
+ (void)port;
+ (void)policy;
+ CALLED(compare_tor_addr_to_addr_policy)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+
+ done:
+ return ADDR_POLICY_ACCEPTED;
+}
+
+int
+NS(geoip_get_country_by_addr)(const tor_addr_t *addr)
+{
+ CALLED(geoip_get_country_by_addr)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+
+ done:
+ return -1;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains, countries_geoip)
+
+/*
+ * Structural test for routerset_contains, when there a matching country
+ * for the address.
+ */
+
+NS_DECL(addr_policy_result_t, compare_tor_addr_to_addr_policy,
+ (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy));
+NS_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int contains = 1;
+ (void)arg;
+
+ NS_MOCK(compare_tor_addr_to_addr_policy);
+ NS_MOCK(geoip_get_country_by_addr);
+
+ set->n_countries = 2;
+ set->countries = bitarray_init_zero(1);
+ bitarray_set(set->countries, 1);
+ contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
+ routerset_free(set);
+
+ tt_int_op(contains, ==, 2);
+ tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
+ tt_int_op(CALLED(geoip_get_country_by_addr), ==, 1);
+
+ done:
+ ;
+}
+
+addr_policy_result_t
+NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
+ const smartlist_t *policy)
+{
+ (void)port;
+ (void)policy;
+ CALLED(compare_tor_addr_to_addr_policy)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+
+ done:
+ return ADDR_POLICY_ACCEPTED;
+}
+
+int
+NS(geoip_get_country_by_addr)(const tor_addr_t *addr)
+{
+ CALLED(geoip_get_country_by_addr)++;
+ tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
+
+ done:
+ return 1;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_add_unknown_ccs, only_flag_and_no_ccs)
+
+/*
+ * Functional test for routerset_add_unknown_ccs, where only_if_some_cc_set
+ * is set and there are no country names.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ routerset_t **setp = &set;
+ int r;
+ (void)arg;
+
+ r = routerset_add_unknown_ccs(setp, 1);
+
+ tt_int_op(r, ==, 0);
+
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_add_unknown_ccs, creates_set)
+
+/*
+ * Functional test for routerset_add_unknown_ccs, where the set argument
+ * is created if passed in as NULL.
+ */
+
+/* The mock is only used to stop the test from asserting erroneously. */
+NS_DECL(country_t, geoip_get_country, (const char *country));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = NULL;
+ routerset_t **setp = &set;
+ int r;
+ (void)arg;
+
+ NS_MOCK(geoip_get_country);
+
+ r = routerset_add_unknown_ccs(setp, 0);
+
+ tt_ptr_op(*setp, !=, NULL);
+ tt_int_op(r, ==, 0);
+
+ done:
+ if (set != NULL)
+ routerset_free(set);
+}
+
+country_t
+NS(geoip_get_country)(const char *country)
+{
+ (void)country;
+ CALLED(geoip_get_country)++;
+
+ return -1;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_add_unknown_ccs, add_unknown)
+
+/*
+ * Structural test for routerset_add_unknown_ccs, that the "{??}"
+ * country code is added to the list.
+ */
+
+NS_DECL(country_t, geoip_get_country, (const char *country));
+NS_DECL(int, geoip_is_loaded, (sa_family_t family));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ routerset_t **setp = &set;
+ int r;
+ (void)arg;
+
+ NS_MOCK(geoip_get_country);
+ NS_MOCK(geoip_is_loaded);
+
+ r = routerset_add_unknown_ccs(setp, 0);
+
+ tt_int_op(r, ==, 1);
+ tt_int_op(smartlist_contains_string(set->country_names, "??"), ==, 1);
+ tt_int_op(smartlist_contains_string(set->list, "{??}"), ==, 1);
+
+ done:
+ if (set != NULL)
+ routerset_free(set);
+}
+
+country_t
+NS(geoip_get_country)(const char *country)
+{
+ int arg_is_qq, arg_is_a1;
+
+ CALLED(geoip_get_country)++;
+
+ arg_is_qq = !strcmp(country, "??");
+ arg_is_a1 = !strcmp(country, "A1");
+
+ tt_int_op(arg_is_qq || arg_is_a1, ==, 1);
+
+ if (arg_is_qq)
+ return 1;
+
+ done:
+ return -1;
+}
+
+int
+NS(geoip_is_loaded)(sa_family_t family)
+{
+ CALLED(geoip_is_loaded)++;
+
+ tt_int_op(family, ==, AF_INET);
+
+ done:
+ return 0;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_add_unknown_ccs, add_a1)
+
+/*
+ * Structural test for routerset_add_unknown_ccs, that the "{a1}"
+ * country code is added to the list.
+ */
+
+NS_DECL(country_t, geoip_get_country, (const char *country));
+NS_DECL(int, geoip_is_loaded, (sa_family_t family));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ routerset_t **setp = &set;
+ int r;
+ (void)arg;
+
+ NS_MOCK(geoip_get_country);
+ NS_MOCK(geoip_is_loaded);
+
+ r = routerset_add_unknown_ccs(setp, 0);
+
+ tt_int_op(r, ==, 1);
+ tt_int_op(smartlist_contains_string(set->country_names, "a1"), ==, 1);
+ tt_int_op(smartlist_contains_string(set->list, "{a1}"), ==, 1);
+
+ done:
+ if (set != NULL)
+ routerset_free(set);
+}
+
+country_t
+NS(geoip_get_country)(const char *country)
+{
+ int arg_is_qq, arg_is_a1;
+
+ CALLED(geoip_get_country)++;
+
+ arg_is_qq = !strcmp(country, "??");
+ arg_is_a1 = !strcmp(country, "A1");
+
+ tt_int_op(arg_is_qq || arg_is_a1, ==, 1);
+
+ if (arg_is_a1)
+ return 1;
+
+ done:
+ return -1;
+}
+
+int
+NS(geoip_is_loaded)(sa_family_t family)
+{
+ CALLED(geoip_is_loaded)++;
+
+ tt_int_op(family, ==, AF_INET);
+
+ done:
+ return 0;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_contains_extendinfo
+
+/*
+ * Functional test for routerset_contains_extendinfo.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ extend_info_t ei;
+ int r;
+ const char *nickname = "foo";
+ (void)arg;
+
+ memset(&ei, 0, sizeof(ei));
+ strmap_set_lc(set->names, nickname, (void *)1);
+ strncpy(ei.nickname, nickname, sizeof(ei.nickname) - 1);
+ ei.nickname[sizeof(ei.nickname) - 1] = '\0';
+
+ r = routerset_contains_extendinfo(set, &ei);
+
+ tt_int_op(r, ==, 4);
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_contains_router
+
+/*
+ * Functional test for routerset_contains_router.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ routerinfo_t ri;
+ country_t country = 1;
+ int r;
+ const char *nickname = "foo";
+ (void)arg;
+
+ memset(&ri, 0, sizeof(ri));
+ strmap_set_lc(set->names, nickname, (void *)1);
+ ri.nickname = (char *)nickname;
+
+ r = routerset_contains_router(set, &ri, country);
+
+ tt_int_op(r, ==, 4);
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_contains_routerstatus
+
+/*
+ * Functional test for routerset_contains_routerstatus.
+ */
+
+// XXX: This is a bit brief. It only populates and tests the nickname fields
+// ie., enough to make the containment check succeed. Perhaps it should do
+// a bit more or test a bit more.
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ routerstatus_t rs;
+ country_t country = 1;
+ int r;
+ const char *nickname = "foo";
+ (void)arg;
+
+ memset(&rs, 0, sizeof(rs));
+ strmap_set_lc(set->names, nickname, (void *)1);
+ strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
+ rs.nickname[sizeof(rs.nickname) - 1] = '\0';
+
+ r = routerset_contains_routerstatus(set, &rs, country);
+
+ tt_int_op(r, ==, 4);
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains_node, none)
+
+/*
+ * Functional test for routerset_contains_node, when the node has no
+ * routerset or routerinfo.
+ */
+
+node_t NS(mock_node);
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int r;
+ (void)arg;
+
+ NS(mock_node).ri = NULL;
+ NS(mock_node).rs = NULL;
+
+ r = routerset_contains_node(set, &NS(mock_node));
+ tt_int_op(r, ==, 0);
+
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains_node, routerstatus)
+
+/*
+ * Functional test for routerset_contains_node, when the node has a
+ * routerset and no routerinfo.
+ */
+
+node_t NS(mock_node);
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int r;
+ const char *nickname = "foo";
+ routerstatus_t rs;
+ (void)arg;
+
+ strmap_set_lc(set->names, nickname, (void *)1);
+
+ strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
+ rs.nickname[sizeof(rs.nickname) - 1] = '\0';
+ NS(mock_node).ri = NULL;
+ NS(mock_node).rs = &rs;
+
+ r = routerset_contains_node(set, &NS(mock_node));
+
+ tt_int_op(r, ==, 4);
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_contains_node, routerinfo)
+
+/*
+ * Functional test for routerset_contains_node, when the node has no
+ * routerset and a routerinfo.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ int r;
+ const char *nickname = "foo";
+ routerinfo_t ri;
+ node_t mock_node;
+ (void)arg;
+
+ strmap_set_lc(set->names, nickname, (void *)1);
+
+ ri.nickname = (char *)nickname;
+ mock_node.ri = &ri;
+ mock_node.rs = NULL;
+
+ r = routerset_contains_node(set, &mock_node);
+
+ tt_int_op(r, ==, 4);
+ done:
+ routerset_free(set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_get_all_nodes, no_routerset)
+
+/*
+ * Functional test for routerset_get_all_nodes, when routerset is NULL or
+ * the routerset list is NULL.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ smartlist_t *out = smartlist_new();
+ routerset_t *set = NULL;
+ (void)arg;
+
+ tt_int_op(smartlist_len(out), ==, 0);
+ routerset_get_all_nodes(out, NULL, NULL, 0);
+
+ tt_int_op(smartlist_len(out), ==, 0);
+
+ set = routerset_new();
+ smartlist_free(set->list);
+ routerset_get_all_nodes(out, NULL, NULL, 0);
+ tt_int_op(smartlist_len(out), ==, 0);
+
+ /* Just recreate list, so we can simply use routerset_free. */
+ set->list = smartlist_new();
+
+ done:
+ routerset_free(set);
+ smartlist_free(out);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_get_all_nodes, list_with_no_nodes)
+
+/*
+ * Structural test for routerset_get_all_nodes, when the routerset list
+ * is empty.
+ */
+
+NS_DECL(const node_t *, node_get_by_nickname,
+ (const char *nickname, int warn_if_unused));
+const char *NS(mock_nickname);
+
+static void
+NS(test_main)(void *arg)
+{
+ smartlist_t *out = smartlist_new();
+ routerset_t *set = routerset_new();
+ int out_len;
+ (void)arg;
+
+ NS_MOCK(node_get_by_nickname);
+
+ NS(mock_nickname) = "foo";
+ smartlist_add(set->list, tor_strdup(NS(mock_nickname)));
+
+ routerset_get_all_nodes(out, set, NULL, 0);
+ out_len = smartlist_len(out);
+
+ smartlist_free(out);
+ routerset_free(set);
+
+ tt_int_op(out_len, ==, 0);
+ tt_int_op(CALLED(node_get_by_nickname), ==, 1);
+
+ done:
+ ;
+}
+
+const node_t *
+NS(node_get_by_nickname)(const char *nickname, int warn_if_unused)
+{
+ CALLED(node_get_by_nickname)++;
+ tt_str_op(nickname, ==, NS(mock_nickname));
+ tt_int_op(warn_if_unused, ==, 1);
+
+ done:
+ return NULL;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_get_all_nodes, list_flag_not_running)
+
+/*
+ * Structural test for routerset_get_all_nodes, with the running_only flag
+ * is set but the nodes are not running.
+ */
+
+NS_DECL(const node_t *, node_get_by_nickname,
+ (const char *nickname, int warn_if_unused));
+const char *NS(mock_nickname);
+node_t NS(mock_node);
+
+static void
+NS(test_main)(void *arg)
+{
+ smartlist_t *out = smartlist_new();
+ routerset_t *set = routerset_new();
+ int out_len;
+ (void)arg;
+
+ NS_MOCK(node_get_by_nickname);
+
+ NS(mock_node).is_running = 0;
+ NS(mock_nickname) = "foo";
+ smartlist_add(set->list, tor_strdup(NS(mock_nickname)));
+
+ routerset_get_all_nodes(out, set, NULL, 1);
+ out_len = smartlist_len(out);
+
+ smartlist_free(out);
+ routerset_free(set);
+
+ tt_int_op(out_len, ==, 0);
+ tt_int_op(CALLED(node_get_by_nickname), ==, 1);
+
+ done:
+ ;
+}
+
+const node_t *
+NS(node_get_by_nickname)(const char *nickname, int warn_if_unused)
+{
+ CALLED(node_get_by_nickname)++;
+ tt_str_op(nickname, ==, NS(mock_nickname));
+ tt_int_op(warn_if_unused, ==, 1);
+
+ done:
+ return &NS(mock_node);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_get_all_nodes, list)
+
+/*
+ * Structural test for routerset_get_all_nodes.
+ */
+
+NS_DECL(const node_t *, node_get_by_nickname,
+ (const char *nickname, int warn_if_unused));
+char *NS(mock_nickname);
+node_t NS(mock_node);
+
+static void
+NS(test_main)(void *arg)
+{
+ smartlist_t *out = smartlist_new();
+ routerset_t *set = routerset_new();
+ int out_len;
+ node_t *ent;
+ (void)arg;
+
+ NS_MOCK(node_get_by_nickname);
+
+ NS(mock_nickname) = tor_strdup("foo");
+ smartlist_add(set->list, NS(mock_nickname));
+
+ routerset_get_all_nodes(out, set, NULL, 0);
+ out_len = smartlist_len(out);
+ ent = (node_t *)smartlist_get(out, 0);
+
+ smartlist_free(out);
+ routerset_free(set);
+
+ tt_int_op(out_len, ==, 1);
+ tt_ptr_op(ent, ==, &NS(mock_node));
+ tt_int_op(CALLED(node_get_by_nickname), ==, 1);
+
+ done:
+ ;
+}
+
+const node_t *
+NS(node_get_by_nickname)(const char *nickname, int warn_if_unused)
+{
+ CALLED(node_get_by_nickname)++;
+ tt_str_op(nickname, ==, NS(mock_nickname));
+ tt_int_op(warn_if_unused, ==, 1);
+
+ done:
+ return &NS(mock_node);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_get_all_nodes, nodelist_with_no_nodes)
+
+/*
+ * Structural test for routerset_get_all_nodes, when the nodelist has no nodes.
+ */
+
+NS_DECL(smartlist_t *, nodelist_get_list, (void));
+
+smartlist_t *NS(mock_smartlist);
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ smartlist_t *out = smartlist_new();
+ int r;
+ (void)arg;
+
+ NS_MOCK(nodelist_get_list);
+
+ smartlist_add(set->country_names, tor_strdup("{xx}"));
+ NS(mock_smartlist) = smartlist_new();
+
+ routerset_get_all_nodes(out, set, NULL, 1);
+ r = smartlist_len(out);
+ routerset_free(set);
+ smartlist_free(out);
+ smartlist_free(NS(mock_smartlist));
+
+ tt_int_op(r, ==, 0);
+ tt_int_op(CALLED(nodelist_get_list), ==, 1);
+
+ done:
+ ;
+}
+
+smartlist_t *
+NS(nodelist_get_list)(void)
+{
+ CALLED(nodelist_get_list)++;
+
+ return NS(mock_smartlist);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_get_all_nodes, nodelist_flag_not_running)
+
+/*
+ * Structural test for routerset_get_all_nodes, with a non-list routerset
+ * the running_only flag is set, but the nodes are not running.
+ */
+
+NS_DECL(smartlist_t *, nodelist_get_list, (void));
+
+smartlist_t *NS(mock_smartlist);
+node_t NS(mock_node);
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ smartlist_t *out = smartlist_new();
+ int r;
+ (void)arg;
+
+ NS_MOCK(nodelist_get_list);
+
+ smartlist_add(set->country_names, tor_strdup("{xx}"));
+ NS(mock_smartlist) = smartlist_new();
+ NS(mock_node).is_running = 0;
+ smartlist_add(NS(mock_smartlist), (void *)&NS(mock_node));
+
+ routerset_get_all_nodes(out, set, NULL, 1);
+ r = smartlist_len(out);
+ routerset_free(set);
+ smartlist_free(out);
+ smartlist_free(NS(mock_smartlist));
+
+ tt_int_op(r, ==, 0);
+ tt_int_op(CALLED(nodelist_get_list), ==, 1);
+
+ done:
+ ;
+}
+
+smartlist_t *
+NS(nodelist_get_list)(void)
+{
+ CALLED(nodelist_get_list)++;
+
+ return NS(mock_smartlist);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_subtract_nodes
+
+/*
+ * Functional test for routerset_subtract_nodes.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = routerset_new();
+ smartlist_t *list = smartlist_new();
+ const char *nickname = "foo";
+ routerinfo_t ri;
+ node_t mock_node;
+ (void)arg;
+
+ strmap_set_lc(set->names, nickname, (void *)1);
+
+ ri.nickname = (char *)nickname;
+ mock_node.rs = NULL;
+ mock_node.ri = &ri;
+ smartlist_add(list, (void *)&mock_node);
+
+ tt_int_op(smartlist_len(list), !=, 0);
+ routerset_subtract_nodes(list, set);
+
+ tt_int_op(smartlist_len(list), ==, 0);
+ done:
+ routerset_free(set);
+ smartlist_free(list);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_subtract_nodes, null_routerset)
+
+/*
+ * Functional test for routerset_subtract_nodes, with a NULL routerset.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = NULL;
+ smartlist_t *list = smartlist_new();
+ const char *nickname = "foo";
+ routerinfo_t ri;
+ node_t mock_node;
+ (void)arg;
+
+ ri.nickname = (char *)nickname;
+ mock_node.ri = &ri;
+ smartlist_add(list, (void *)&mock_node);
+
+ tt_int_op(smartlist_len(list), !=, 0);
+ routerset_subtract_nodes(list, set);
+
+ tt_int_op(smartlist_len(list), !=, 0);
+ done:
+ routerset_free(set);
+ smartlist_free(list);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_to_string
+
+/*
+ * Functional test for routerset_to_string.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *set = NULL;
+ char *s = NULL;
+ (void)arg;
+
+ set = NULL;
+ s = routerset_to_string(set);
+ tt_str_op(s, ==, "");
+ tor_free(s);
+
+ set = routerset_new();
+ s = routerset_to_string(set);
+ tt_str_op(s, ==, "");
+ tor_free(s);
+ routerset_free(set); set = NULL;
+
+ set = routerset_new();
+ smartlist_add(set->list, tor_strndup("a", 1));
+ s = routerset_to_string(set);
+ tt_str_op(s, ==, "a");
+ tor_free(s);
+ routerset_free(set); set = NULL;
+
+ set = routerset_new();
+ smartlist_add(set->list, tor_strndup("a", 1));
+ smartlist_add(set->list, tor_strndup("b", 1));
+ s = routerset_to_string(set);
+ tt_str_op(s, ==, "a,b");
+ tor_free(s);
+ routerset_free(set); set = NULL;
+
+ done:
+ tor_free(s);
+ routerset_free((routerset_t *)set);
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_equal, empty_empty)
+
+/*
+ * Functional test for routerset_equal, with both routersets empty.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *a = routerset_new(), *b = routerset_new();
+ int r;
+ (void)arg;
+
+ r = routerset_equal(a, b);
+ routerset_free(a);
+ routerset_free(b);
+
+ tt_int_op(r, ==, 1);
+
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_equal, empty_not_empty)
+
+/*
+ * Functional test for routerset_equal, with one routersets empty.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *a = routerset_new(), *b = routerset_new();
+ int r;
+ (void)arg;
+
+ smartlist_add(b->list, tor_strdup("{xx}"));
+ r = routerset_equal(a, b);
+ routerset_free(a);
+ routerset_free(b);
+
+ tt_int_op(r, ==, 0);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_equal, differing_lengths)
+
+/*
+ * Functional test for routerset_equal, with the routersets having
+ * differing lengths.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *a = routerset_new(), *b = routerset_new();
+ int r;
+ (void)arg;
+
+ smartlist_add(a->list, tor_strdup("{aa}"));
+ smartlist_add(b->list, tor_strdup("{b1}"));
+ smartlist_add(b->list, tor_strdup("{b2}"));
+ r = routerset_equal(a, b);
+ routerset_free(a);
+ routerset_free(b);
+
+ tt_int_op(r, ==, 0);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_equal, unequal)
+
+/*
+ * Functional test for routerset_equal, with the routersets being
+ * different.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *a = routerset_new(), *b = routerset_new();
+ int r;
+ (void)arg;
+
+ smartlist_add(a->list, tor_strdup("foo"));
+ smartlist_add(b->list, tor_strdup("bar"));
+ r = routerset_equal(a, b);
+ routerset_free(a);
+ routerset_free(b);
+
+ tt_int_op(r, ==, 0);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_equal, equal)
+
+/*
+ * Functional test for routerset_equal, with the routersets being
+ * equal.
+ */
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *a = routerset_new(), *b = routerset_new();
+ int r;
+ (void)arg;
+
+ smartlist_add(a->list, tor_strdup("foo"));
+ smartlist_add(b->list, tor_strdup("foo"));
+ r = routerset_equal(a, b);
+ routerset_free(a);
+ routerset_free(b);
+
+ tt_int_op(r, ==, 1);
+ done:
+ ;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE ASPECT(routerset_free, null_routerset)
+
+/*
+ * Structural test for routerset_free, where the routerset is NULL.
+ */
+
+NS_DECL(void, smartlist_free, (smartlist_t *sl));
+
+static void
+NS(test_main)(void *arg)
+{
+ (void)arg;
+
+ NS_MOCK(smartlist_free);
+
+ routerset_free(NULL);
+
+ tt_int_op(CALLED(smartlist_free), ==, 0);
+
+ done:
+ ;
+}
+
+void
+NS(smartlist_free)(smartlist_t *s)
+{
+ (void)s;
+ CALLED(smartlist_free)++;
+}
+
+#undef NS_SUBMODULE
+#define NS_SUBMODULE routerset_free
+
+/*
+ * Structural test for routerset_free.
+ */
+
+NS_DECL(void, smartlist_free, (smartlist_t *sl));
+NS_DECL(void, strmap_free,(strmap_t *map, void (*free_val)(void*)));
+NS_DECL(void, digestmap_free, (digestmap_t *map, void (*free_val)(void*)));
+
+static void
+NS(test_main)(void *arg)
+{
+ routerset_t *routerset = routerset_new();
+ (void)arg;
+
+ NS_MOCK(smartlist_free);
+ NS_MOCK(strmap_free);
+ NS_MOCK(digestmap_free);
+
+ routerset_free(routerset);
+
+ tt_int_op(CALLED(smartlist_free), !=, 0);
+ tt_int_op(CALLED(strmap_free), !=, 0);
+ tt_int_op(CALLED(digestmap_free), !=, 0);
+
+ done:
+ ;
+}
+
+void
+NS(smartlist_free)(smartlist_t *s)
+{
+ CALLED(smartlist_free)++;
+ smartlist_free__real(s);
+}
+
+void
+NS(strmap_free)(strmap_t *map, void (*free_val)(void*))
+{
+ CALLED(strmap_free)++;
+ strmap_free__real(map, free_val);
+}
+
+void
+NS(digestmap_free)(digestmap_t *map, void (*free_val)(void*))
+{
+ CALLED(digestmap_free)++;
+ digestmap_free__real(map, free_val);
+}
+
+#undef NS_SUBMODULE
+
+struct testcase_t routerset_tests[] = {
+ TEST_CASE(routerset_new),
+ TEST_CASE(routerset_get_countryname),
+ TEST_CASE(routerset_is_list),
+ TEST_CASE(routerset_needs_geoip),
+ TEST_CASE(routerset_is_empty),
+ TEST_CASE_ASPECT(routerset_contains, null_set_or_null_set_list),
+ TEST_CASE_ASPECT(routerset_contains, set_and_nickname),
+ TEST_CASE_ASPECT(routerset_contains, set_and_null_nickname),
+ TEST_CASE_ASPECT(routerset_contains, set_and_no_nickname),
+ TEST_CASE_ASPECT(routerset_contains, set_and_digest),
+ TEST_CASE_ASPECT(routerset_contains, set_and_no_digest),
+ TEST_CASE_ASPECT(routerset_contains, set_and_null_digest),
+ TEST_CASE_ASPECT(routerset_contains, set_and_addr),
+ TEST_CASE_ASPECT(routerset_contains, set_and_no_addr),
+ TEST_CASE_ASPECT(routerset_contains, set_and_null_addr),
+ TEST_CASE_ASPECT(routerset_contains, countries_no_geoip),
+ TEST_CASE_ASPECT(routerset_contains, countries_geoip),
+ TEST_CASE_ASPECT(routerset_add_unknown_ccs, only_flag_and_no_ccs),
+ TEST_CASE_ASPECT(routerset_add_unknown_ccs, creates_set),
+ TEST_CASE_ASPECT(routerset_add_unknown_ccs, add_unknown),
+ TEST_CASE_ASPECT(routerset_add_unknown_ccs, add_a1),
+ TEST_CASE(routerset_contains_extendinfo),
+ TEST_CASE(routerset_contains_router),
+ TEST_CASE(routerset_contains_routerstatus),
+ TEST_CASE_ASPECT(routerset_contains_node, none),
+ TEST_CASE_ASPECT(routerset_contains_node, routerinfo),
+ TEST_CASE_ASPECT(routerset_contains_node, routerstatus),
+ TEST_CASE_ASPECT(routerset_get_all_nodes, no_routerset),
+ TEST_CASE_ASPECT(routerset_get_all_nodes, list_with_no_nodes),
+ TEST_CASE_ASPECT(routerset_get_all_nodes, list_flag_not_running),
+ TEST_CASE_ASPECT(routerset_get_all_nodes, list),
+ TEST_CASE_ASPECT(routerset_get_all_nodes, nodelist_with_no_nodes),
+ TEST_CASE_ASPECT(routerset_get_all_nodes, nodelist_flag_not_running),
+ TEST_CASE_ASPECT(routerset_refresh_counties, geoip_not_loaded),
+ TEST_CASE_ASPECT(routerset_refresh_counties, no_countries),
+ TEST_CASE_ASPECT(routerset_refresh_counties, one_valid_country),
+ TEST_CASE_ASPECT(routerset_refresh_counties, one_invalid_country),
+ TEST_CASE_ASPECT(routerset_union, source_bad),
+ TEST_CASE_ASPECT(routerset_union, one),
+ TEST_CASE_ASPECT(routerset_parse, malformed),
+ TEST_CASE_ASPECT(routerset_parse, valid_hexdigest),
+ TEST_CASE_ASPECT(routerset_parse, valid_nickname),
+ TEST_CASE_ASPECT(routerset_parse, get_countryname),
+ TEST_CASE_ASPECT(routerset_parse, policy),
+ TEST_CASE(routerset_subtract_nodes),
+ TEST_CASE_ASPECT(routerset_subtract_nodes, null_routerset),
+ TEST_CASE(routerset_to_string),
+ TEST_CASE_ASPECT(routerset_equal, empty_empty),
+ TEST_CASE_ASPECT(routerset_equal, empty_not_empty),
+ TEST_CASE_ASPECT(routerset_equal, differing_lengths),
+ TEST_CASE_ASPECT(routerset_equal, unequal),
+ TEST_CASE_ASPECT(routerset_equal, equal),
+ TEST_CASE_ASPECT(routerset_free, null_routerset),
+ TEST_CASE(routerset_free),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_socks.c b/src/test/test_socks.c
index 4ce61e068b..2b8f824b50 100644
--- a/src/test/test_socks.c
+++ b/src/test/test_socks.c
@@ -61,10 +61,10 @@ test_socks_4_unsupported_commands(void *ptr)
/* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */
ADD_DATA(buf, "\x04\x02\x11\x11\x02\x02\x02\x02\x00");
- test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks) == -1);
- test_eq(4, socks->socks_version);
- test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
+ tt_int_op(4,==, socks->socks_version);
+ tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */
done:
;
@@ -76,49 +76,49 @@ test_socks_4_supported_commands(void *ptr)
{
SOCKS_TEST_INIT();
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
/* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */
ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
- test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks) == 1);
- test_eq(4, socks->socks_version);
- test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
- test_eq(SOCKS_COMMAND_CONNECT, socks->command);
- test_streq("2.2.2.3", socks->address);
- test_eq(4370, socks->port);
- test_assert(socks->got_auth == 0);
- test_assert(! socks->username);
-
- test_eq(0, buf_datalen(buf));
+ tt_int_op(4,==, socks->socks_version);
+ tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */
+ tt_int_op(SOCKS_COMMAND_CONNECT,==, socks->command);
+ tt_str_op("2.2.2.3",==, socks->address);
+ tt_int_op(4370,==, socks->port);
+ tt_assert(socks->got_auth == 0);
+ tt_assert(! socks->username);
+
+ tt_int_op(0,==, buf_datalen(buf));
socks_request_clear(socks);
/* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/
ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
- test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks) == 1);
- test_eq(4, socks->socks_version);
- test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
- test_eq(SOCKS_COMMAND_CONNECT, socks->command);
- test_streq("2.2.2.4", socks->address);
- test_eq(4370, socks->port);
- test_assert(socks->got_auth == 1);
- test_assert(socks->username);
- test_eq(2, socks->usernamelen);
- test_memeq("me", socks->username, 2);
-
- test_eq(0, buf_datalen(buf));
+ tt_int_op(4,==, socks->socks_version);
+ tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */
+ tt_int_op(SOCKS_COMMAND_CONNECT,==, socks->command);
+ tt_str_op("2.2.2.4",==, socks->address);
+ tt_int_op(4370,==, socks->port);
+ tt_assert(socks->got_auth == 1);
+ tt_assert(socks->username);
+ tt_int_op(2,==, socks->usernamelen);
+ tt_mem_op("me",==, socks->username, 2);
+
+ tt_int_op(0,==, buf_datalen(buf));
socks_request_clear(socks);
/* SOCKS 4a Send RESOLVE [F0] request for torproject.org */
ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00");
- test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks) == 1);
- test_eq(4, socks->socks_version);
- test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */
- test_streq("torproject.org", socks->address);
+ tt_int_op(4,==, socks->socks_version);
+ tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */
+ tt_str_op("torproject.org",==, socks->address);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
done:
;
@@ -133,33 +133,43 @@ test_socks_5_unsupported_commands(void *ptr)
/* SOCKS 5 Send unsupported BIND [02] command */
ADD_DATA(buf, "\x05\x02\x00\x01");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), 0);
- test_eq(0, buf_datalen(buf));
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(0, socks->reply[1]);
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, 0);
+ tt_int_op(0,==, buf_datalen(buf));
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
ADD_DATA(buf, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), -1);
- /* XXX: shouldn't tor reply 'command not supported' [07]? */
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, -1);
+
+ tt_int_op(5,==,socks->socks_version);
+ tt_int_op(10,==,socks->replylen);
+ tt_int_op(5,==,socks->reply[0]);
+ tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,==,socks->reply[1]);
+ tt_int_op(1,==,socks->reply[3]);
buf_clear(buf);
socks_request_clear(socks);
/* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */
- ADD_DATA(buf, "\x05\x03\x00\x01\x02");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), 0);
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(2, socks->reply[1]);
+ ADD_DATA(buf, "\x05\x02\x00\x01");
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, 0);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
ADD_DATA(buf, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), -1);
- /* XXX: shouldn't tor reply 'command not supported' [07]? */
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, -1);
+
+ tt_int_op(5,==,socks->socks_version);
+ tt_int_op(10,==,socks->replylen);
+ tt_int_op(5,==,socks->reply[0]);
+ tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,==,socks->reply[1]);
+ tt_int_op(1,==,socks->reply[3]);
done:
;
@@ -173,64 +183,64 @@ test_socks_5_supported_commands(void *ptr)
/* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
ADD_DATA(buf, "\x05\x01\x00");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), 0);
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(0, socks->reply[1]);
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, 0);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), 1);
- test_streq("2.2.2.2", socks->address);
- test_eq(4369, socks->port);
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, 1);
+ tt_str_op("2.2.2.2",==, socks->address);
+ tt_int_op(4369,==, socks->port);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
socks_request_clear(socks);
/* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */
ADD_DATA(buf, "\x05\x01\x00");
ADD_DATA(buf, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11");
- test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
- get_options()->SafeSocks), 1);
+ tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ get_options()->SafeSocks),==, 1);
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(0, socks->reply[1]);
- test_streq("torproject.org", socks->address);
- test_eq(4369, socks->port);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
+ tt_str_op("torproject.org",==, socks->address);
+ tt_int_op(4369,==, socks->port);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
socks_request_clear(socks);
/* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */
ADD_DATA(buf, "\x05\x01\x00");
ADD_DATA(buf, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02");
- test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks) == 1);
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(0, socks->reply[1]);
- test_streq("torproject.org", socks->address);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
+ tt_str_op("torproject.org",==, socks->address);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
socks_request_clear(socks);
/* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */
ADD_DATA(buf, "\x05\x01\x00");
ADD_DATA(buf, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03");
- test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+ tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks) == 1);
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(0, socks->reply[1]);
- test_streq("2.2.2.5", socks->address);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
+ tt_str_op("2.2.2.5",==, socks->address);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
done:
;
@@ -244,30 +254,30 @@ test_socks_5_no_authenticate(void *ptr)
/*SOCKS 5 No Authentication */
ADD_DATA(buf,"\x05\x01\x00");
- test_assert(!fetch_from_buf_socks(buf, socks,
+ tt_assert(!fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks));
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(SOCKS_NO_AUTH, socks->reply[1]);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(SOCKS_NO_AUTH,==, socks->reply[1]);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
/*SOCKS 5 Send username/password anyway - pretend to be broken */
ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01");
- test_assert(!fetch_from_buf_socks(buf, socks,
+ tt_assert(!fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks));
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(1, socks->reply[0]);
- test_eq(0, socks->reply[1]);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(1,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
- test_eq(2, socks->usernamelen);
- test_eq(2, socks->passwordlen);
+ tt_int_op(2,==, socks->usernamelen);
+ tt_int_op(2,==, socks->passwordlen);
- test_memeq("\x01\x01", socks->username, 2);
- test_memeq("\x01\x01", socks->password, 2);
+ tt_mem_op("\x01\x01",==, socks->username, 2);
+ tt_mem_op("\x01\x01",==, socks->password, 2);
done:
;
@@ -282,31 +292,31 @@ test_socks_5_authenticate(void *ptr)
/* SOCKS 5 Negotiate username/password authentication */
ADD_DATA(buf, "\x05\x01\x02");
- test_assert(!fetch_from_buf_socks(buf, socks,
+ tt_assert(!fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks));
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(SOCKS_USER_PASS, socks->reply[1]);
- test_eq(5, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(SOCKS_USER_PASS,==, socks->reply[1]);
+ tt_int_op(5,==, socks->socks_version);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
/* SOCKS 5 Send username/password */
ADD_DATA(buf, "\x01\x02me\x08mypasswd");
- test_assert(!fetch_from_buf_socks(buf, socks,
+ tt_assert(!fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks));
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(1, socks->reply[0]);
- test_eq(0, socks->reply[1]);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(1,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
- test_eq(2, socks->usernamelen);
- test_eq(8, socks->passwordlen);
+ tt_int_op(2,==, socks->usernamelen);
+ tt_int_op(8,==, socks->passwordlen);
- test_memeq("me", socks->username, 2);
- test_memeq("mypasswd", socks->password, 8);
+ tt_mem_op("me",==, socks->username, 2);
+ tt_mem_op("mypasswd",==, socks->password, 8);
done:
;
@@ -321,34 +331,34 @@ test_socks_5_authenticate_with_data(void *ptr)
/* SOCKS 5 Negotiate username/password authentication */
ADD_DATA(buf, "\x05\x01\x02");
- test_assert(!fetch_from_buf_socks(buf, socks,
+ tt_assert(!fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks));
- test_eq(2, socks->replylen);
- test_eq(5, socks->reply[0]);
- test_eq(SOCKS_USER_PASS, socks->reply[1]);
- test_eq(5, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(5,==, socks->reply[0]);
+ tt_int_op(SOCKS_USER_PASS,==, socks->reply[1]);
+ tt_int_op(5,==, socks->socks_version);
- test_eq(0, buf_datalen(buf));
+ tt_int_op(0,==, buf_datalen(buf));
/* SOCKS 5 Send username/password */
/* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
- test_assert(fetch_from_buf_socks(buf, socks,
+ tt_assert(fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks) == 1);
- test_eq(5, socks->socks_version);
- test_eq(2, socks->replylen);
- test_eq(1, socks->reply[0]);
- test_eq(0, socks->reply[1]);
+ tt_int_op(5,==, socks->socks_version);
+ tt_int_op(2,==, socks->replylen);
+ tt_int_op(1,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
- test_streq("2.2.2.2", socks->address);
- test_eq(4369, socks->port);
+ tt_str_op("2.2.2.2",==, socks->address);
+ tt_int_op(4369,==, socks->port);
- test_eq(2, socks->usernamelen);
- test_eq(3, socks->passwordlen);
- test_memeq("me", socks->username, 2);
- test_memeq("you", socks->password, 3);
+ tt_int_op(2,==, socks->usernamelen);
+ tt_int_op(3,==, socks->passwordlen);
+ tt_mem_op("me",==, socks->username, 2);
+ tt_mem_op("you",==, socks->password, 3);
done:
;
@@ -362,13 +372,13 @@ test_socks_5_auth_before_negotiation(void *ptr)
/* SOCKS 5 Send username/password */
ADD_DATA(buf, "\x01\x02me\x02me");
- test_assert(fetch_from_buf_socks(buf, socks,
+ tt_assert(fetch_from_buf_socks(buf, socks,
get_options()->TestSocks,
get_options()->SafeSocks) == -1);
- test_eq(0, socks->socks_version);
- test_eq(0, socks->replylen);
- test_eq(0, socks->reply[0]);
- test_eq(0, socks->reply[1]);
+ tt_int_op(0,==, socks->socks_version);
+ tt_int_op(0,==, socks->replylen);
+ tt_int_op(0,==, socks->reply[0]);
+ tt_int_op(0,==, socks->reply[1]);
done:
;
diff --git a/src/test/test_status.c b/src/test/test_status.c
index 46dd473132..8bc0152ffb 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -30,27 +30,24 @@
* global circuits.
*/
-struct global_circuitlist_s mock_global_circuitlist =
- TOR_LIST_HEAD_INITIALIZER(global_circuitlist);
+static smartlist_t * mock_global_circuitlist = NULL;
-NS_DECL(struct global_circuitlist_s *, circuit_get_global_list, (void));
+NS_DECL(smartlist_t *, circuit_get_global_list, (void));
static void
NS(test_main)(void *arg)
{
/* Choose origin_circuit_t wlog. */
origin_circuit_t *mock_circuit1, *mock_circuit2;
- circuit_t *circ, *tmp;
int expected_circuits = 2, actual_circuits;
(void)arg;
mock_circuit1 = tor_malloc_zero(sizeof(origin_circuit_t));
mock_circuit2 = tor_malloc_zero(sizeof(origin_circuit_t));
- TOR_LIST_INSERT_HEAD(
- &mock_global_circuitlist, TO_CIRCUIT(mock_circuit1), head);
- TOR_LIST_INSERT_HEAD(
- &mock_global_circuitlist, TO_CIRCUIT(mock_circuit2), head);
+ mock_global_circuitlist = smartlist_new();
+ smartlist_add(mock_global_circuitlist, TO_CIRCUIT(mock_circuit1));
+ smartlist_add(mock_global_circuitlist, TO_CIRCUIT(mock_circuit2));
NS_MOCK(circuit_get_global_list);
@@ -58,17 +55,18 @@ NS(test_main)(void *arg)
tt_assert(expected_circuits == actual_circuits);
- done:
- TOR_LIST_FOREACH_SAFE(
- circ, NS(circuit_get_global_list)(), head, tmp);
- tor_free(circ);
- NS_UNMOCK(circuit_get_global_list);
+ done:
+ tor_free(mock_circuit1);
+ tor_free(mock_circuit2);
+ smartlist_free(mock_global_circuitlist);
+ mock_global_circuitlist = NULL;
+ NS_UNMOCK(circuit_get_global_list);
}
-static struct global_circuitlist_s *
+static smartlist_t *
NS(circuit_get_global_list)(void)
{
- return &mock_global_circuitlist;
+ return mock_global_circuitlist;
}
#undef NS_SUBMODULE
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 151ec69127..c67aa71b02 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -64,8 +64,8 @@ test_util_read_until_eof_impl(const char *fname, size_t file_len,
else
tt_int_op(sz, ==, file_len);
- test_mem_op(test_str, ==, str, sz);
- test_assert(str[sz] == '\0');
+ tt_mem_op(test_str, ==, str, sz);
+ tt_int_op(str[sz], ==, '\0');
done:
unlink(fifo_name);
@@ -87,6 +87,20 @@ test_util_read_file_eof_tiny_limit(void *arg)
}
static void
+test_util_read_file_eof_one_loop_a(void *arg)
+{
+ (void)arg;
+ test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
+}
+
+static void
+test_util_read_file_eof_one_loop_b(void *arg)
+{
+ (void)arg;
+ test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
+}
+
+static void
test_util_read_file_eof_two_loops(void *arg)
{
(void)arg;
@@ -98,6 +112,14 @@ test_util_read_file_eof_two_loops(void *arg)
}
static void
+test_util_read_file_eof_two_loops_b(void *arg)
+{
+ (void)arg;
+
+ test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
+}
+
+static void
test_util_read_file_eof_zero_bytes(void *arg)
{
(void)arg;
@@ -155,7 +177,7 @@ test_util_write_chunks_to_file(void *arg)
str = read_file_to_str(fname, RFTS_BIN, &st);
tt_assert(str != NULL);
tt_u64_op((uint64_t)st.st_size, ==, data_str_len);
- test_mem_op(data_str, ==, str, data_str_len);
+ tt_mem_op(data_str, ==, str, data_str_len);
tor_free(str);
// assert that the tempfile is removed (should not leave artifacts)
@@ -186,14 +208,14 @@ test_util_write_chunks_to_file(void *arg)
str = read_file_to_str(fname, RFTS_BIN, &st);
tt_assert(str != NULL);
tt_u64_op((uint64_t)st.st_size, ==, data_str_len);
- test_mem_op(data_str, ==, str, data_str_len);
+ tt_mem_op(data_str, ==, str, data_str_len);
tor_free(str);
// assert the tempfile still contains the known string
str = read_file_to_str(tempname, RFTS_BIN, &st);
tt_assert(str != NULL);
tt_u64_op((uint64_t)st.st_size, ==, temp_str_len);
- test_mem_op(temp_str, ==, str, temp_str_len);
+ tt_mem_op(temp_str, ==, str, temp_str_len);
done:
unlink(fname);
@@ -207,7 +229,7 @@ test_util_write_chunks_to_file(void *arg)
}
static void
-test_util_time(void)
+test_util_time(void *arg)
{
struct timeval start, end;
struct tm a_time;
@@ -218,29 +240,30 @@ test_util_time(void)
/* Test tv_udiff */
+ (void)arg;
start.tv_sec = 5;
start.tv_usec = 5000;
end.tv_sec = 5;
end.tv_usec = 5000;
- test_eq(0L, tv_udiff(&start, &end));
+ tt_int_op(0L,==, tv_udiff(&start, &end));
end.tv_usec = 7000;
- test_eq(2000L, tv_udiff(&start, &end));
+ tt_int_op(2000L,==, tv_udiff(&start, &end));
end.tv_sec = 6;
- test_eq(1002000L, tv_udiff(&start, &end));
+ tt_int_op(1002000L,==, tv_udiff(&start, &end));
end.tv_usec = 0;
- test_eq(995000L, tv_udiff(&start, &end));
+ tt_int_op(995000L,==, tv_udiff(&start, &end));
end.tv_sec = 4;
- test_eq(-1005000L, tv_udiff(&start, &end));
+ tt_int_op(-1005000L,==, tv_udiff(&start, &end));
/* Test tor_timegm */
@@ -252,45 +275,53 @@ test_util_time(void)
a_time.tm_hour = 6;
a_time.tm_min = 14;
a_time.tm_sec = 55;
- test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
+ tt_int_op((time_t) 1062224095UL,==, tor_timegm(&a_time));
a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
- test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
+ tt_int_op((time_t) 1093846495UL,==, tor_timegm(&a_time));
a_time.tm_mon = 1; /* Try a leap year, in feb. */
a_time.tm_mday = 10;
- test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
+ tt_int_op((time_t) 1076393695UL,==, tor_timegm(&a_time));
a_time.tm_mon = 0;
a_time.tm_mday = 10;
- test_eq((time_t) 1073715295UL, tor_timegm(&a_time));
+ tt_int_op((time_t) 1073715295UL,==, tor_timegm(&a_time));
a_time.tm_mon = 12; /* Wrong month, it's 0-based */
a_time.tm_mday = 10;
- test_eq((time_t) -1, tor_timegm(&a_time));
+ tt_int_op((time_t) -1,==, tor_timegm(&a_time));
a_time.tm_mon = -1; /* Wrong month */
a_time.tm_mday = 10;
- test_eq((time_t) -1, tor_timegm(&a_time));
+ tt_int_op((time_t) -1,==, tor_timegm(&a_time));
/* Test {format,parse}_rfc1123_time */
format_rfc1123_time(timestr, 0);
- test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
+ tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",==, timestr);
format_rfc1123_time(timestr, (time_t)1091580502UL);
- test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
+ tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",==, timestr);
t_res = 0;
i = parse_rfc1123_time(timestr, &t_res);
- test_eq(0,i);
- test_eq(t_res, (time_t)1091580502UL);
+ tt_int_op(0,==, i);
+ tt_int_op(t_res,==, (time_t)1091580502UL);
/* The timezone doesn't matter */
t_res = 0;
- test_eq(0, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
- test_eq(t_res, (time_t)1091580502UL);
- test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
- test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
+ tt_int_op(0,==, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
+ tt_int_op(t_res,==, (time_t)1091580502UL);
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
+ tt_int_op(-1,==,
+ parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
#if 0
/* This fails, I imagine it's important and should be fixed? */
@@ -304,31 +335,31 @@ test_util_time(void)
t_res = 0;
i = parse_iso_time("", &t_res);
- test_eq(-1, i);
+ tt_int_op(-1,==, i);
t_res = 0;
i = parse_iso_time("2004-08-32 00:48:22", &t_res);
- test_eq(-1, i);
+ tt_int_op(-1,==, i);
t_res = 0;
i = parse_iso_time("1969-08-03 00:48:22", &t_res);
- test_eq(-1, i);
+ tt_int_op(-1,==, i);
t_res = 0;
i = parse_iso_time("2004-08-04 00:48:22", &t_res);
- test_eq(0,i);
- test_eq(t_res, (time_t)1091580502UL);
+ tt_int_op(0,==, i);
+ tt_int_op(t_res,==, (time_t)1091580502UL);
t_res = 0;
i = parse_iso_time("2004-8-4 0:48:22", &t_res);
- test_eq(0, i);
- test_eq(t_res, (time_t)1091580502UL);
- test_eq(-1, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res));
- test_eq(-1, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res));
- test_eq(-1, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res));
- test_eq(-1, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res));
- test_eq(-1, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res));
- test_eq(-1, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res));
- test_eq(-1, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res));
- test_eq(-1, parse_iso_time("2147483647-08-29 14:00:00", &t_res));
- test_eq(-1, parse_iso_time("2011-03-30 23:59", &t_res));
+ tt_int_op(0,==, i);
+ tt_int_op(t_res,==, (time_t)1091580502UL);
+ tt_int_op(-1,==, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2147483647-08-29 14:00:00", &t_res));
+ tt_int_op(-1,==, parse_iso_time("2011-03-30 23:59", &t_res));
/* Test tor_gettimeofday */
@@ -348,7 +379,7 @@ test_util_time(void)
tv.tv_sec = (time_t)1326296338;
tv.tv_usec = 3060;
format_iso_time(timestr, (time_t)tv.tv_sec);
- test_streq("2012-01-11 15:38:58", timestr);
+ tt_str_op("2012-01-11 15:38:58",==, timestr);
/* The output of format_local_iso_time will vary by timezone, and setting
our timezone for testing purposes would be a nontrivial flaky pain.
Skip this test for now.
@@ -356,11 +387,11 @@ test_util_time(void)
test_streq("2012-01-11 10:38:58", timestr);
*/
format_iso_time_nospace(timestr, (time_t)tv.tv_sec);
- test_streq("2012-01-11T15:38:58", timestr);
- test_eq(strlen(timestr), ISO_TIME_LEN);
+ tt_str_op("2012-01-11T15:38:58",==, timestr);
+ tt_int_op(strlen(timestr),==, ISO_TIME_LEN);
format_iso_time_nospace_usec(timestr, &tv);
- test_streq("2012-01-11T15:38:58.003060", timestr);
- test_eq(strlen(timestr), ISO_TIME_USEC_LEN);
+ tt_str_op("2012-01-11T15:38:58.003060",==, timestr);
+ tt_int_op(strlen(timestr),==, ISO_TIME_USEC_LEN);
done:
;
@@ -381,55 +412,66 @@ test_util_parse_http_time(void *arg)
/* Test parse_http_time */
- test_eq(-1, parse_http_time("", &a_time));
- test_eq(-1, parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time));
- test_eq(-1, parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time));
- test_eq(-1, parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time));
- test_eq(-1, parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time));
- test_eq(-1, parse_http_time("Sunday, August the third", &a_time));
- test_eq(-1, parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time));
-
- test_eq(0, parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(-1,==,
+ parse_http_time("", &a_time));
+ tt_int_op(-1,==,
+ parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time));
+ tt_int_op(-1,==,
+ parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time));
+ tt_int_op(-1,==,
+ parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time));
+ tt_int_op(-1,==,
+ parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time));
+ tt_int_op(-1,==,
+ parse_http_time("Sunday, August the third", &a_time));
+ tt_int_op(-1,==,
+ parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time));
+
+ tt_int_op(0,==,
+ parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==,
+ parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==,
+ parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==,
+ parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time));
- test_eq((time_t)775961302UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time));
+ tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time));
T("1994-08-04 00:48:22");
- test_eq(0, parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time));
- test_eq((time_t)1325376000UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time));
+ tt_int_op((time_t)1325376000UL,==, tor_timegm(&a_time));
T("2012-01-01 00:00:00");
- test_eq(0, parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time));
- test_eq((time_t)1356912000UL, tor_timegm(&a_time));
+ tt_int_op(0,==, parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time));
+ tt_int_op((time_t)1356912000UL,==, tor_timegm(&a_time));
T("2012-12-31 00:00:00");
- test_eq(-1, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time));
- test_eq(-1, parse_http_time("2011-03-32 00:00:00 GMT", &a_time));
- test_eq(-1, parse_http_time("2011-03-30 24:00:00 GMT", &a_time));
- test_eq(-1, parse_http_time("2011-03-30 23:60:00 GMT", &a_time));
- test_eq(-1, parse_http_time("2011-03-30 23:59:62 GMT", &a_time));
- test_eq(-1, parse_http_time("1969-03-30 23:59:59 GMT", &a_time));
- test_eq(-1, parse_http_time("2011-00-30 23:59:59 GMT", &a_time));
- test_eq(-1, parse_http_time("2011-03-30 23:59", &a_time));
+ tt_int_op(-1,==, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("2011-03-32 00:00:00 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("2011-03-30 24:00:00 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("2011-03-30 23:60:00 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("2011-03-30 23:59:62 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("1969-03-30 23:59:59 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("2011-00-30 23:59:59 GMT", &a_time));
+ tt_int_op(-1,==, parse_http_time("2011-03-30 23:59", &a_time));
#undef T
done:
@@ -437,13 +479,14 @@ test_util_parse_http_time(void *arg)
}
static void
-test_util_config_line(void)
+test_util_config_line(void *arg)
{
char buf[1024];
char *k=NULL, *v=NULL;
const char *str;
/* Test parse_config_line_from_str */
+ (void)arg;
strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
"k2\n"
"k3 \n" "\n" " \n" "#comment\n"
@@ -463,110 +506,110 @@ test_util_config_line(void)
str = buf;
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k");
- test_streq(v, "v");
+ tt_str_op(k,==, "k");
+ tt_str_op(v,==, "v");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "key value with"));
+ tt_assert(!strcmpstart(str, "key value with"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "key");
- test_streq(v, "value with spaces");
+ tt_str_op(k,==, "key");
+ tt_str_op(v,==, "value with spaces");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "keykey"));
+ tt_assert(!strcmpstart(str, "keykey"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "keykey");
- test_streq(v, "val");
+ tt_str_op(k,==, "keykey");
+ tt_str_op(v,==, "val");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k2\n"));
+ tt_assert(!strcmpstart(str, "k2\n"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k2");
- test_streq(v, "");
+ tt_str_op(k,==, "k2");
+ tt_str_op(v,==, "");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k3 \n"));
+ tt_assert(!strcmpstart(str, "k3 \n"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k3");
- test_streq(v, "");
+ tt_str_op(k,==, "k3");
+ tt_str_op(v,==, "");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "#comment"));
+ tt_assert(!strcmpstart(str, "#comment"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k4");
- test_streq(v, "");
+ tt_str_op(k,==, "k4");
+ tt_str_op(v,==, "");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k5#abc"));
+ tt_assert(!strcmpstart(str, "k5#abc"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k5");
- test_streq(v, "");
+ tt_str_op(k,==, "k5");
+ tt_str_op(v,==, "");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k6"));
+ tt_assert(!strcmpstart(str, "k6"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k6");
- test_streq(v, "val");
+ tt_str_op(k,==, "k6");
+ tt_str_op(v,==, "val");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "kseven"));
+ tt_assert(!strcmpstart(str, "kseven"));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "kseven");
- test_streq(v, "a quoted \'string");
+ tt_str_op(k,==, "kseven");
+ tt_str_op(v,==, "a quoted \'string");
tor_free(k); tor_free(v);
- test_assert(!strcmpstart(str, "k8 "));
+ tt_assert(!strcmpstart(str, "k8 "));
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k8");
- test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
+ tt_str_op(k,==, "k8");
+ tt_str_op(v,==, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k9");
- test_streq(v, "a line that spans two lines.");
+ tt_str_op(k,==, "k9");
+ tt_str_op(v,==, "a line that spans two lines.");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k10");
- test_streq(v, "more than one continuation");
+ tt_str_op(k,==, "k10");
+ tt_str_op(v,==, "more than one continuation");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k11");
- test_streq(v, "continuation at the start");
+ tt_str_op(k,==, "k11");
+ tt_str_op(v,==, "continuation at the start");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k12");
- test_streq(v, "line with a embedded");
+ tt_str_op(k,==, "k12");
+ tt_str_op(v,==, "line with a embedded");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k13");
- test_streq(v, "continuation at the very start");
+ tt_str_op(k,==, "k13");
+ tt_str_op(v,==, "continuation at the very start");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k14");
- test_streq(v, "a line that has a comment and" );
+ tt_str_op(k,==, "k14");
+ tt_str_op(v,==, "a line that has a comment and" );
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k15");
- test_streq(v, "this should be the next new line");
+ tt_str_op(k,==, "k15");
+ tt_str_op(v,==, "this should be the next new line");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k16");
- test_streq(v, "a line that has a comment and" );
+ tt_str_op(k,==, "k16");
+ tt_str_op(v,==, "a line that has a comment and" );
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k17");
- test_streq(v, "this should be the next new line");
+ tt_str_op(k,==, "k17");
+ tt_str_op(v,==, "this should be the next new line");
tor_free(k); tor_free(v);
- test_streq(str, "");
+ tt_str_op(str,==, "");
done:
tor_free(k);
@@ -574,7 +617,7 @@ test_util_config_line(void)
}
static void
-test_util_config_line_quotes(void)
+test_util_config_line_quotes(void *arg)
{
char buf1[1024];
char buf2[128];
@@ -584,6 +627,7 @@ test_util_config_line_quotes(void)
const char *str;
/* Test parse_config_line_from_str */
+ (void)arg;
strlcpy(buf1, "kTrailingSpace \"quoted value\" \n"
"kTrailingGarbage \"quoted value\"trailing garbage\n"
, sizeof(buf1));
@@ -596,30 +640,30 @@ test_util_config_line_quotes(void)
str = buf1;
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "kTrailingSpace");
- test_streq(v, "quoted value");
+ tt_str_op(k,==, "kTrailingSpace");
+ tt_str_op(v,==, "quoted value");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
str = buf2;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
str = buf3;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
str = buf4;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
done:
@@ -628,13 +672,14 @@ test_util_config_line_quotes(void)
}
static void
-test_util_config_line_comment_character(void)
+test_util_config_line_comment_character(void *arg)
{
char buf[1024];
char *k=NULL, *v=NULL;
const char *str;
/* Test parse_config_line_from_str */
+ (void)arg;
strlcpy(buf, "k1 \"# in quotes\"\n"
"k2 some value # some comment\n"
"k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
@@ -642,16 +687,16 @@ test_util_config_line_comment_character(void)
str = buf;
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k1");
- test_streq(v, "# in quotes");
+ tt_str_op(k,==, "k1");
+ tt_str_op(v,==, "# in quotes");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "k2");
- test_streq(v, "some value");
+ tt_str_op(k,==, "k2");
+ tt_str_op(v,==, "some value");
tor_free(k); tor_free(v);
- test_streq(str, "k3 /home/user/myTorNetwork#2\n");
+ tt_str_op(str,==, "k3 /home/user/myTorNetwork#2\n");
#if 0
str = parse_config_line_from_str(str, &k, &v);
@@ -668,7 +713,7 @@ test_util_config_line_comment_character(void)
}
static void
-test_util_config_line_escaped_content(void)
+test_util_config_line_escaped_content(void *arg)
{
char buf1[1024];
char buf2[128];
@@ -680,6 +725,7 @@ test_util_config_line_escaped_content(void)
const char *str;
/* Test parse_config_line_from_str */
+ (void)arg;
strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n"
"HexadecimalUpper \"\\x2A\"\n"
"HexadecimalUpperX \"\\X2A\"\n"
@@ -711,91 +757,91 @@ test_util_config_line_escaped_content(void)
str = buf1;
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "HexadecimalLower");
- test_streq(v, "*");
+ tt_str_op(k,==, "HexadecimalLower");
+ tt_str_op(v,==, "*");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "HexadecimalUpper");
- test_streq(v, "*");
+ tt_str_op(k,==, "HexadecimalUpper");
+ tt_str_op(v,==, "*");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "HexadecimalUpperX");
- test_streq(v, "*");
+ tt_str_op(k,==, "HexadecimalUpperX");
+ tt_str_op(v,==, "*");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "Octal");
- test_streq(v, "*");
+ tt_str_op(k,==, "Octal");
+ tt_str_op(v,==, "*");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "Newline");
- test_streq(v, "\n");
+ tt_str_op(k,==, "Newline");
+ tt_str_op(v,==, "\n");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "Tab");
- test_streq(v, "\t");
+ tt_str_op(k,==, "Tab");
+ tt_str_op(v,==, "\t");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "CarriageReturn");
- test_streq(v, "\r");
+ tt_str_op(k,==, "CarriageReturn");
+ tt_str_op(v,==, "\r");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "DoubleQuote");
- test_streq(v, "\"");
+ tt_str_op(k,==, "DoubleQuote");
+ tt_str_op(v,==, "\"");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "SimpleQuote");
- test_streq(v, "'");
+ tt_str_op(k,==, "SimpleQuote");
+ tt_str_op(v,==, "'");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "Backslash");
- test_streq(v, "\\");
+ tt_str_op(k,==, "Backslash");
+ tt_str_op(v,==, "\\");
tor_free(k); tor_free(v);
str = parse_config_line_from_str(str, &k, &v);
- test_streq(k, "Mix");
- test_streq(v, "This is a \"star\":\t'*'\nAnd second line");
+ tt_str_op(k,==, "Mix");
+ tt_str_op(v,==, "This is a \"star\":\t'*'\nAnd second line");
tor_free(k); tor_free(v);
- test_streq(str, "");
+ tt_str_op(str,==, "");
str = buf2;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
str = buf3;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
str = buf4;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
#if 0
str = buf5;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str, ==, NULL);
tor_free(k); tor_free(v);
#endif
str = buf6;
str = parse_config_line_from_str(str, &k, &v);
- test_eq_ptr(str, NULL);
+ tt_ptr_op(str,==, NULL);
tor_free(k); tor_free(v);
done:
@@ -805,46 +851,47 @@ test_util_config_line_escaped_content(void)
#ifndef _WIN32
static void
-test_util_expand_filename(void)
+test_util_expand_filename(void *arg)
{
char *str;
+ (void)arg;
setenv("HOME", "/home/itv", 1); /* For "internal test value" */
str = expand_filename("");
- test_streq("", str);
+ tt_str_op("",==, str);
tor_free(str);
str = expand_filename("/normal/path");
- test_streq("/normal/path", str);
+ tt_str_op("/normal/path",==, str);
tor_free(str);
str = expand_filename("/normal/trailing/path/");
- test_streq("/normal/trailing/path/", str);
+ tt_str_op("/normal/trailing/path/",==, str);
tor_free(str);
str = expand_filename("~");
- test_streq("/home/itv/", str);
+ tt_str_op("/home/itv/",==, str);
tor_free(str);
str = expand_filename("$HOME/nodice");
- test_streq("$HOME/nodice", str);
+ tt_str_op("$HOME/nodice",==, str);
tor_free(str);
str = expand_filename("~/");
- test_streq("/home/itv/", str);
+ tt_str_op("/home/itv/",==, str);
tor_free(str);
str = expand_filename("~/foobarqux");
- test_streq("/home/itv/foobarqux", str);
+ tt_str_op("/home/itv/foobarqux",==, str);
tor_free(str);
str = expand_filename("~/../../etc/passwd");
- test_streq("/home/itv/../../etc/passwd", str);
+ tt_str_op("/home/itv/../../etc/passwd",==, str);
tor_free(str);
str = expand_filename("~/trailing/");
- test_streq("/home/itv/trailing/", str);
+ tt_str_op("/home/itv/trailing/",==, str);
tor_free(str);
/* Ideally we'd test ~anotheruser, but that's shady to test (we'd
have to somehow inject/fake the get_user_homedir call) */
@@ -853,15 +900,15 @@ test_util_expand_filename(void)
setenv("HOME", "/home/itv/", 1);
str = expand_filename("~");
- test_streq("/home/itv/", str);
+ tt_str_op("/home/itv/",==, str);
tor_free(str);
str = expand_filename("~/");
- test_streq("/home/itv/", str);
+ tt_str_op("/home/itv/",==, str);
tor_free(str);
str = expand_filename("~/foo");
- test_streq("/home/itv/foo", str);
+ tt_str_op("/home/itv/foo",==, str);
tor_free(str);
/* Try with empty $HOME */
@@ -869,15 +916,15 @@ test_util_expand_filename(void)
setenv("HOME", "", 1);
str = expand_filename("~");
- test_streq("/", str);
+ tt_str_op("/",==, str);
tor_free(str);
str = expand_filename("~/");
- test_streq("/", str);
+ tt_str_op("/",==, str);
tor_free(str);
str = expand_filename("~/foobar");
- test_streq("/foobar", str);
+ tt_str_op("/foobar",==, str);
tor_free(str);
/* Try with $HOME unset */
@@ -885,15 +932,15 @@ test_util_expand_filename(void)
unsetenv("HOME");
str = expand_filename("~");
- test_streq("/", str);
+ tt_str_op("/",==, str);
tor_free(str);
str = expand_filename("~/");
- test_streq("/", str);
+ tt_str_op("/",==, str);
tor_free(str);
str = expand_filename("~/foobar");
- test_streq("/foobar", str);
+ tt_str_op("/foobar",==, str);
tor_free(str);
done:
@@ -903,37 +950,38 @@ test_util_expand_filename(void)
/** Test tor_escape_str_for_pt_args(). */
static void
-test_util_escape_string_socks(void)
+test_util_escape_string_socks(void *arg)
{
char *escaped_string = NULL;
/** Simple backslash escape. */
+ (void)arg;
escaped_string = tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
- test_assert(escaped_string);
- test_streq(escaped_string, "This is a backslash: \\\\");
+ tt_assert(escaped_string);
+ tt_str_op(escaped_string,==, "This is a backslash: \\\\");
tor_free(escaped_string);
/** Simple semicolon escape. */
escaped_string = tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
- test_assert(escaped_string);
- test_streq(escaped_string, "First rule:Do not use \\;");
+ tt_assert(escaped_string);
+ tt_str_op(escaped_string,==, "First rule:Do not use \\;");
tor_free(escaped_string);
/** Empty string. */
escaped_string = tor_escape_str_for_pt_args("", ";\\");
- test_assert(escaped_string);
- test_streq(escaped_string, "");
+ tt_assert(escaped_string);
+ tt_str_op(escaped_string,==, "");
tor_free(escaped_string);
/** Escape all characters. */
escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\");
- test_assert(escaped_string);
- test_streq(escaped_string, "\\;\\\\\\;\\\\");
+ tt_assert(escaped_string);
+ tt_str_op(escaped_string,==, "\\;\\\\\\;\\\\");
tor_free(escaped_string);
escaped_string = tor_escape_str_for_pt_args(";", ";\\");
- test_assert(escaped_string);
- test_streq(escaped_string, "\\;");
+ tt_assert(escaped_string);
+ tt_str_op(escaped_string,==, "\\;");
tor_free(escaped_string);
done:
@@ -944,288 +992,290 @@ static void
test_util_string_is_key_value(void *ptr)
{
(void)ptr;
- test_assert(string_is_key_value(LOG_WARN, "key=value"));
- test_assert(string_is_key_value(LOG_WARN, "k=v"));
- test_assert(string_is_key_value(LOG_WARN, "key="));
- test_assert(string_is_key_value(LOG_WARN, "x="));
- test_assert(string_is_key_value(LOG_WARN, "xx="));
- test_assert(!string_is_key_value(LOG_WARN, "=value"));
- test_assert(!string_is_key_value(LOG_WARN, "=x"));
- test_assert(!string_is_key_value(LOG_WARN, "="));
+ tt_assert(string_is_key_value(LOG_WARN, "key=value"));
+ tt_assert(string_is_key_value(LOG_WARN, "k=v"));
+ tt_assert(string_is_key_value(LOG_WARN, "key="));
+ tt_assert(string_is_key_value(LOG_WARN, "x="));
+ tt_assert(string_is_key_value(LOG_WARN, "xx="));
+ tt_assert(!string_is_key_value(LOG_WARN, "=value"));
+ tt_assert(!string_is_key_value(LOG_WARN, "=x"));
+ tt_assert(!string_is_key_value(LOG_WARN, "="));
/* ??? */
- /* test_assert(!string_is_key_value(LOG_WARN, "===")); */
+ /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
done:
;
}
/** Test basic string functionality. */
static void
-test_util_strmisc(void)
+test_util_strmisc(void *arg)
{
char buf[1024];
int i;
char *cp, *cp_tmp = NULL;
/* Test strl operations */
- test_eq(5, strlcpy(buf, "Hello", 0));
- test_eq(5, strlcpy(buf, "Hello", 10));
- test_streq(buf, "Hello");
- test_eq(5, strlcpy(buf, "Hello", 6));
- test_streq(buf, "Hello");
- test_eq(5, strlcpy(buf, "Hello", 5));
- test_streq(buf, "Hell");
+ (void)arg;
+ tt_int_op(5,==, strlcpy(buf, "Hello", 0));
+ tt_int_op(5,==, strlcpy(buf, "Hello", 10));
+ tt_str_op(buf,==, "Hello");
+ tt_int_op(5,==, strlcpy(buf, "Hello", 6));
+ tt_str_op(buf,==, "Hello");
+ tt_int_op(5,==, strlcpy(buf, "Hello", 5));
+ tt_str_op(buf,==, "Hell");
strlcpy(buf, "Hello", sizeof(buf));
- test_eq(10, strlcat(buf, "Hello", 5));
+ tt_int_op(10,==, strlcat(buf, "Hello", 5));
/* Test strstrip() */
strlcpy(buf, "Testing 1 2 3", sizeof(buf));
tor_strstrip(buf, ",!");
- test_streq(buf, "Testing 1 2 3");
+ tt_str_op(buf,==, "Testing 1 2 3");
strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
tor_strstrip(buf, "!? ");
- test_streq(buf, "Testing123");
+ tt_str_op(buf,==, "Testing123");
strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf));
tor_strstrip(buf, "!? ");
- test_streq(buf, "Testing123");
+ tt_str_op(buf,==, "Testing123");
/* Test parse_long */
/* Empty/zero input */
- test_eq(0L, tor_parse_long("",10,0,100,&i,NULL));
- test_eq(0, i);
- test_eq(0L, tor_parse_long("0",10,0,100,&i,NULL));
- test_eq(1, i);
+ tt_int_op(0L,==, tor_parse_long("",10,0,100,&i,NULL));
+ tt_int_op(0,==, i);
+ tt_int_op(0L,==, tor_parse_long("0",10,0,100,&i,NULL));
+ tt_int_op(1,==, i);
/* Normal cases */
- test_eq(10L, tor_parse_long("10",10,0,100,&i,NULL));
- test_eq(1, i);
- test_eq(10L, tor_parse_long("10",10,0,10,&i,NULL));
- test_eq(1, i);
- test_eq(10L, tor_parse_long("10",10,10,100,&i,NULL));
- test_eq(1, i);
- test_eq(-50L, tor_parse_long("-50",10,-100,100,&i,NULL));
- test_eq(1, i);
- test_eq(-50L, tor_parse_long("-50",10,-100,0,&i,NULL));
- test_eq(1, i);
- test_eq(-50L, tor_parse_long("-50",10,-50,0,&i,NULL));
- test_eq(1, i);
+ tt_int_op(10L,==, tor_parse_long("10",10,0,100,&i,NULL));
+ tt_int_op(1,==, i);
+ tt_int_op(10L,==, tor_parse_long("10",10,0,10,&i,NULL));
+ tt_int_op(1,==, i);
+ tt_int_op(10L,==, tor_parse_long("10",10,10,100,&i,NULL));
+ tt_int_op(1,==, i);
+ tt_int_op(-50L,==, tor_parse_long("-50",10,-100,100,&i,NULL));
+ tt_int_op(1,==, i);
+ tt_int_op(-50L,==, tor_parse_long("-50",10,-100,0,&i,NULL));
+ tt_int_op(1,==, i);
+ tt_int_op(-50L,==, tor_parse_long("-50",10,-50,0,&i,NULL));
+ tt_int_op(1,==, i);
/* Extra garbage */
- test_eq(0L, tor_parse_long("10m",10,0,100,&i,NULL));
- test_eq(0, i);
- test_eq(0L, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
- test_eq(0, i);
- test_eq(10L, tor_parse_long("10m",10,0,100,&i,&cp));
- test_eq(1, i);
- test_streq(cp, "m");
- test_eq(-50L, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
- test_eq(1, i);
- test_streq(cp, " plus garbage");
+ tt_int_op(0L,==, tor_parse_long("10m",10,0,100,&i,NULL));
+ tt_int_op(0,==, i);
+ tt_int_op(0L,==, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
+ tt_int_op(0,==, i);
+ tt_int_op(10L,==, tor_parse_long("10m",10,0,100,&i,&cp));
+ tt_int_op(1,==, i);
+ tt_str_op(cp,==, "m");
+ tt_int_op(-50L,==, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
+ tt_int_op(1,==, i);
+ tt_str_op(cp,==, " plus garbage");
/* Out of bounds */
- test_eq(0L, tor_parse_long("10",10,50,100,&i,NULL));
- test_eq(0, i);
- test_eq(0L, tor_parse_long("-50",10,0,100,&i,NULL));
- test_eq(0, i);
+ tt_int_op(0L,==, tor_parse_long("10",10,50,100,&i,NULL));
+ tt_int_op(0,==, i);
+ tt_int_op(0L,==, tor_parse_long("-50",10,0,100,&i,NULL));
+ tt_int_op(0,==, i);
/* Base different than 10 */
- test_eq(2L, tor_parse_long("10",2,0,100,NULL,NULL));
- test_eq(0L, tor_parse_long("2",2,0,100,NULL,NULL));
- test_eq(0L, tor_parse_long("10",-2,0,100,NULL,NULL));
- test_eq(68284L, tor_parse_long("10abc",16,0,70000,NULL,NULL));
- test_eq(68284L, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
- test_eq(0, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
- test_eq(i, 0);
+ tt_int_op(2L,==, tor_parse_long("10",2,0,100,NULL,NULL));
+ tt_int_op(0L,==, tor_parse_long("2",2,0,100,NULL,NULL));
+ tt_int_op(0L,==, tor_parse_long("10",-2,0,100,NULL,NULL));
+ tt_int_op(68284L,==, tor_parse_long("10abc",16,0,70000,NULL,NULL));
+ tt_int_op(68284L,==, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
+ tt_int_op(0,==, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
+ tt_int_op(i,==, 0);
/* Test parse_ulong */
- test_eq(0UL, tor_parse_ulong("",10,0,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("0",10,0,100,NULL,NULL));
- test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
- test_eq(10UL, tor_parse_ulong("10",10,0,10,NULL,NULL));
- test_eq(10UL, tor_parse_ulong("10",10,10,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("8",8,0,100,NULL,NULL));
- test_eq(50UL, tor_parse_ulong("50",10,50,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("-50",10,-100,100,NULL,NULL));
- test_eq(0UL, tor_parse_ulong("50",-1,50,100,&i,NULL));
- test_eq(0, i);
+ tt_int_op(0UL,==, tor_parse_ulong("",10,0,100,NULL,NULL));
+ tt_int_op(0UL,==, tor_parse_ulong("0",10,0,100,NULL,NULL));
+ tt_int_op(10UL,==, tor_parse_ulong("10",10,0,100,NULL,NULL));
+ tt_int_op(0UL,==, tor_parse_ulong("10",10,50,100,NULL,NULL));
+ tt_int_op(10UL,==, tor_parse_ulong("10",10,0,10,NULL,NULL));
+ tt_int_op(10UL,==, tor_parse_ulong("10",10,10,100,NULL,NULL));
+ tt_int_op(0UL,==, tor_parse_ulong("8",8,0,100,NULL,NULL));
+ tt_int_op(50UL,==, tor_parse_ulong("50",10,50,100,NULL,NULL));
+ tt_int_op(0UL,==, tor_parse_ulong("-50",10,-100,100,NULL,NULL));
+ tt_int_op(0UL,==, tor_parse_ulong("50",-1,50,100,&i,NULL));
+ tt_int_op(0,==, i);
/* Test parse_uint64 */
- test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
- test_eq(1, i);
- test_streq(cp, " x");
- test_assert(U64_LITERAL(12345678901) ==
+ tt_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
+ tt_int_op(1,==, i);
+ tt_str_op(cp,==, " x");
+ tt_assert(U64_LITERAL(12345678901) ==
tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
- test_eq(1, i);
- test_streq(cp, "");
- test_assert(U64_LITERAL(0) ==
+ tt_int_op(1,==, i);
+ tt_str_op(cp,==, "");
+ tt_assert(U64_LITERAL(0) ==
tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
- test_eq(0, i);
- test_assert(U64_LITERAL(0) ==
+ tt_int_op(0,==, i);
+ tt_assert(U64_LITERAL(0) ==
tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
- test_eq(0, i);
+ tt_int_op(0,==, i);
{
/* Test parse_double */
double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL);
- test_eq(1, i);
- test_assert(DBL_TO_U64(d) == 10);
+ tt_int_op(1,==, i);
+ tt_assert(DBL_TO_U64(d) == 10);
d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL);
- test_eq(1, i);
- test_assert(DBL_TO_U64(d) == 0);
+ tt_int_op(1,==, i);
+ tt_assert(DBL_TO_U64(d) == 0);
d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL);
- test_eq(0, i);
+ tt_int_op(0,==, i);
d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL);
- test_eq(0, i);
+ tt_int_op(0,==, i);
d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp);
- test_eq(1, i);
+ tt_int_op(1,==, i);
d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL);
- test_eq(1, i);
- test_assert(DBL_TO_U64(d) == 0);
+ tt_int_op(1,==, i);
+ tt_assert(DBL_TO_U64(d) == 0);
d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
- test_eq(1, i);
- test_eq(-10.0, d);
+ tt_int_op(1,==, i);
+ tt_int_op(-10.0,==, d);
}
{
/* Test tor_parse_* where we overflow/underflow the underlying type. */
/* This string should overflow 64-bit ints. */
#define TOOBIG "100000000000000000000000000"
- test_eq(0L, tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
- test_eq(i, 0);
- test_eq(0L, tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
- test_eq(i, 0);
- test_eq(0UL, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
- test_eq(i, 0);
+ tt_int_op(0L,==, tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
+ tt_int_op(i,==, 0);
+ tt_int_op(0L,==,
+ tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
+ tt_int_op(i,==, 0);
+ tt_int_op(0UL,==, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
+ tt_int_op(i,==, 0);
tt_u64_op(U64_LITERAL(0), ==, tor_parse_uint64(TOOBIG, 10,
0, UINT64_MAX, &i, NULL));
- test_eq(i, 0);
+ tt_int_op(i,==, 0);
}
/* Test snprintf */
/* Returning -1 when there's not enough room in the output buffer */
- test_eq(-1, tor_snprintf(buf, 0, "Foo"));
- test_eq(-1, tor_snprintf(buf, 2, "Foo"));
- test_eq(-1, tor_snprintf(buf, 3, "Foo"));
- test_neq(-1, tor_snprintf(buf, 4, "Foo"));
+ tt_int_op(-1,==, tor_snprintf(buf, 0, "Foo"));
+ tt_int_op(-1,==, tor_snprintf(buf, 2, "Foo"));
+ tt_int_op(-1,==, tor_snprintf(buf, 3, "Foo"));
+ tt_int_op(-1,!=, tor_snprintf(buf, 4, "Foo"));
/* Always NUL-terminate the output */
tor_snprintf(buf, 5, "abcdef");
- test_eq(0, buf[4]);
+ tt_int_op(0,==, buf[4]);
tor_snprintf(buf, 10, "abcdef");
- test_eq(0, buf[6]);
+ tt_int_op(0,==, buf[6]);
/* uint64 */
tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
U64_PRINTF_ARG(U64_LITERAL(12345678901)));
- test_streq("x!12345678901!x", buf);
+ tt_str_op("x!12345678901!x",==, buf);
/* Test str{,case}cmpstart */
- test_assert(strcmpstart("abcdef", "abcdef")==0);
- test_assert(strcmpstart("abcdef", "abc")==0);
- test_assert(strcmpstart("abcdef", "abd")<0);
- test_assert(strcmpstart("abcdef", "abb")>0);
- test_assert(strcmpstart("ab", "abb")<0);
- test_assert(strcmpstart("ab", "")==0);
- test_assert(strcmpstart("ab", "ab ")<0);
- test_assert(strcasecmpstart("abcdef", "abCdEF")==0);
- test_assert(strcasecmpstart("abcDeF", "abc")==0);
- test_assert(strcasecmpstart("abcdef", "Abd")<0);
- test_assert(strcasecmpstart("Abcdef", "abb")>0);
- test_assert(strcasecmpstart("ab", "Abb")<0);
- test_assert(strcasecmpstart("ab", "")==0);
- test_assert(strcasecmpstart("ab", "ab ")<0);
+ tt_assert(strcmpstart("abcdef", "abcdef")==0);
+ tt_assert(strcmpstart("abcdef", "abc")==0);
+ tt_assert(strcmpstart("abcdef", "abd")<0);
+ tt_assert(strcmpstart("abcdef", "abb")>0);
+ tt_assert(strcmpstart("ab", "abb")<0);
+ tt_assert(strcmpstart("ab", "")==0);
+ tt_assert(strcmpstart("ab", "ab ")<0);
+ tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
+ tt_assert(strcasecmpstart("abcDeF", "abc")==0);
+ tt_assert(strcasecmpstart("abcdef", "Abd")<0);
+ tt_assert(strcasecmpstart("Abcdef", "abb")>0);
+ tt_assert(strcasecmpstart("ab", "Abb")<0);
+ tt_assert(strcasecmpstart("ab", "")==0);
+ tt_assert(strcasecmpstart("ab", "ab ")<0);
/* Test str{,case}cmpend */
- test_assert(strcmpend("abcdef", "abcdef")==0);
- test_assert(strcmpend("abcdef", "def")==0);
- test_assert(strcmpend("abcdef", "deg")<0);
- test_assert(strcmpend("abcdef", "dee")>0);
- test_assert(strcmpend("ab", "aab")>0);
- test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
- test_assert(strcasecmpend("abcdef", "dEF")==0);
- test_assert(strcasecmpend("abcdef", "Deg")<0);
- test_assert(strcasecmpend("abcDef", "dee")>0);
- test_assert(strcasecmpend("AB", "abb")<0);
+ tt_assert(strcmpend("abcdef", "abcdef")==0);
+ tt_assert(strcmpend("abcdef", "def")==0);
+ tt_assert(strcmpend("abcdef", "deg")<0);
+ tt_assert(strcmpend("abcdef", "dee")>0);
+ tt_assert(strcmpend("ab", "aab")>0);
+ tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
+ tt_assert(strcasecmpend("abcdef", "dEF")==0);
+ tt_assert(strcasecmpend("abcdef", "Deg")<0);
+ tt_assert(strcasecmpend("abcDef", "dee")>0);
+ tt_assert(strcasecmpend("AB", "abb")<0);
/* Test digest_is_zero */
memset(buf,0,20);
buf[20] = 'x';
- test_assert(tor_digest_is_zero(buf));
+ tt_assert(tor_digest_is_zero(buf));
buf[19] = 'x';
- test_assert(!tor_digest_is_zero(buf));
+ tt_assert(!tor_digest_is_zero(buf));
/* Test mem_is_zero */
memset(buf,0,128);
buf[128] = 'x';
- test_assert(tor_mem_is_zero(buf, 10));
- test_assert(tor_mem_is_zero(buf, 20));
- test_assert(tor_mem_is_zero(buf, 128));
- test_assert(!tor_mem_is_zero(buf, 129));
+ tt_assert(tor_mem_is_zero(buf, 10));
+ tt_assert(tor_mem_is_zero(buf, 20));
+ tt_assert(tor_mem_is_zero(buf, 128));
+ tt_assert(!tor_mem_is_zero(buf, 129));
buf[60] = (char)255;
- test_assert(!tor_mem_is_zero(buf, 128));
+ tt_assert(!tor_mem_is_zero(buf, 128));
buf[0] = (char)1;
- test_assert(!tor_mem_is_zero(buf, 10));
+ tt_assert(!tor_mem_is_zero(buf, 10));
/* Test 'escaped' */
- test_assert(NULL == escaped(NULL));
- test_streq("\"\"", escaped(""));
- test_streq("\"abcd\"", escaped("abcd"));
- test_streq("\"\\\\ \\n\\r\\t\\\"\\'\"", escaped("\\ \n\r\t\"'"));
- test_streq("\"unnecessary \\'backslashes\\'\"",
+ tt_assert(NULL == escaped(NULL));
+ tt_str_op("\"\"",==, escaped(""));
+ tt_str_op("\"abcd\"",==, escaped("abcd"));
+ tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",==, escaped("\\ \n\r\t\"'"));
+ tt_str_op("\"unnecessary \\'backslashes\\'\"",==,
escaped("unnecessary \'backslashes\'"));
/* Non-printable characters appear as octal */
- test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
- test_streq("\"z\\336\\255 ;foo\"", escaped("z\xde\xad\x20;foo"));
+ tt_str_op("\"z\\001abc\\277d\"",==, escaped("z\001abc\277d"));
+ tt_str_op("\"z\\336\\255 ;foo\"",==, escaped("z\xde\xad\x20;foo"));
/* Test strndup and memdup */
{
const char *s = "abcdefghijklmnopqrstuvwxyz";
cp_tmp = tor_strndup(s, 30);
- test_streq(cp_tmp, s); /* same string, */
- test_neq_ptr(cp_tmp, s); /* but different pointers. */
+ tt_str_op(cp_tmp,==, s); /* same string, */
+ tt_ptr_op(cp_tmp,!=,s); /* but different pointers. */
tor_free(cp_tmp);
cp_tmp = tor_strndup(s, 5);
- test_streq(cp_tmp, "abcde");
+ tt_str_op(cp_tmp,==, "abcde");
tor_free(cp_tmp);
s = "a\0b\0c\0d\0e\0";
cp_tmp = tor_memdup(s,10);
- test_memeq(cp_tmp, s, 10); /* same ram, */
- test_neq_ptr(cp_tmp, s); /* but different pointers. */
+ tt_mem_op(cp_tmp,==, s, 10); /* same ram, */
+ tt_ptr_op(cp_tmp,!=,s); /* but different pointers. */
tor_free(cp_tmp);
}
/* Test str-foo functions */
cp_tmp = tor_strdup("abcdef");
- test_assert(tor_strisnonupper(cp_tmp));
+ tt_assert(tor_strisnonupper(cp_tmp));
cp_tmp[3] = 'D';
- test_assert(!tor_strisnonupper(cp_tmp));
+ tt_assert(!tor_strisnonupper(cp_tmp));
tor_strupper(cp_tmp);
- test_streq(cp_tmp, "ABCDEF");
+ tt_str_op(cp_tmp,==, "ABCDEF");
tor_strlower(cp_tmp);
- test_streq(cp_tmp, "abcdef");
- test_assert(tor_strisnonupper(cp_tmp));
- test_assert(tor_strisprint(cp_tmp));
+ tt_str_op(cp_tmp,==, "abcdef");
+ tt_assert(tor_strisnonupper(cp_tmp));
+ tt_assert(tor_strisprint(cp_tmp));
cp_tmp[3] = 3;
- test_assert(!tor_strisprint(cp_tmp));
+ tt_assert(!tor_strisprint(cp_tmp));
tor_free(cp_tmp);
/* Test memmem and memstr */
{
const char *haystack = "abcde";
- test_assert(!tor_memmem(haystack, 5, "ef", 2));
- test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
- test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
- test_assert(!tor_memmem(haystack, 4, "cde", 3));
+ tt_assert(!tor_memmem(haystack, 5, "ef", 2));
+ tt_ptr_op(tor_memmem(haystack, 5, "cd", 2),==, haystack + 2);
+ tt_ptr_op(tor_memmem(haystack, 5, "cde", 3),==, haystack + 2);
+ tt_assert(!tor_memmem(haystack, 4, "cde", 3));
haystack = "ababcad";
- test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
- test_eq_ptr(tor_memmem(haystack, 7, "ad", 2), haystack + 5);
- test_eq_ptr(tor_memmem(haystack, 7, "cad", 3), haystack + 4);
- test_assert(!tor_memmem(haystack, 7, "dadad", 5));
- test_assert(!tor_memmem(haystack, 7, "abcdefghij", 10));
+ tt_ptr_op(tor_memmem(haystack, 7, "abc", 3),==, haystack + 2);
+ tt_ptr_op(tor_memmem(haystack, 7, "ad", 2),==, haystack + 5);
+ tt_ptr_op(tor_memmem(haystack, 7, "cad", 3),==, haystack + 4);
+ tt_assert(!tor_memmem(haystack, 7, "dadad", 5));
+ tt_assert(!tor_memmem(haystack, 7, "abcdefghij", 10));
/* memstr */
- test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
- test_eq_ptr(tor_memstr(haystack, 7, "cad"), haystack + 4);
- test_assert(!tor_memstr(haystack, 6, "cad"));
- test_assert(!tor_memstr(haystack, 7, "cadd"));
- test_assert(!tor_memstr(haystack, 7, "fe"));
- test_assert(!tor_memstr(haystack, 7, "ababcade"));
+ tt_ptr_op(tor_memstr(haystack, 7, "abc"),==, haystack + 2);
+ tt_ptr_op(tor_memstr(haystack, 7, "cad"),==, haystack + 4);
+ tt_assert(!tor_memstr(haystack, 6, "cad"));
+ tt_assert(!tor_memstr(haystack, 7, "cadd"));
+ tt_assert(!tor_memstr(haystack, 7, "fe"));
+ tt_assert(!tor_memstr(haystack, 7, "ababcade"));
}
/* Test hex_str */
@@ -1234,19 +1284,20 @@ test_util_strmisc(void)
size_t i;
for (i = 0; i < sizeof(binary_data); ++i)
binary_data[i] = i;
- test_streq(hex_str(binary_data, 0), "");
- test_streq(hex_str(binary_data, 1), "00");
- test_streq(hex_str(binary_data, 17), "000102030405060708090A0B0C0D0E0F10");
- test_streq(hex_str(binary_data, 32),
+ tt_str_op(hex_str(binary_data, 0),==, "");
+ tt_str_op(hex_str(binary_data, 1),==, "00");
+ tt_str_op(hex_str(binary_data, 17),==,
+ "000102030405060708090A0B0C0D0E0F10");
+ tt_str_op(hex_str(binary_data, 32),==,
"000102030405060708090A0B0C0D0E0F"
"101112131415161718191A1B1C1D1E1F");
- test_streq(hex_str(binary_data, 34),
+ tt_str_op(hex_str(binary_data, 34),==,
"000102030405060708090A0B0C0D0E0F"
"101112131415161718191A1B1C1D1E1F");
/* Repeat these tests for shorter strings after longer strings
have been tried, to make sure we're correctly terminating strings */
- test_streq(hex_str(binary_data, 1), "00");
- test_streq(hex_str(binary_data, 0), "");
+ tt_str_op(hex_str(binary_data, 1),==, "00");
+ tt_str_op(hex_str(binary_data, 0),==, "");
}
/* Test strcmp_opt */
@@ -1275,20 +1326,21 @@ test_util_strmisc(void)
}
static void
-test_util_pow2(void)
+test_util_pow2(void *arg)
{
/* Test tor_log2(). */
- test_eq(tor_log2(64), 6);
- test_eq(tor_log2(65), 6);
- test_eq(tor_log2(63), 5);
- test_eq(tor_log2(0), 0); /* incorrect mathematically, but as specified */
- test_eq(tor_log2(1), 0);
- test_eq(tor_log2(2), 1);
- test_eq(tor_log2(3), 1);
- test_eq(tor_log2(4), 2);
- test_eq(tor_log2(5), 2);
- test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
- test_eq(tor_log2(UINT64_MAX), 63);
+ (void)arg;
+ tt_int_op(tor_log2(64),==, 6);
+ tt_int_op(tor_log2(65),==, 6);
+ tt_int_op(tor_log2(63),==, 5);
+ tt_int_op(tor_log2(0),==, 0);/* incorrect mathematically, but as specified */
+ tt_int_op(tor_log2(1),==, 0);
+ tt_int_op(tor_log2(2),==, 1);
+ tt_int_op(tor_log2(3),==, 1);
+ tt_int_op(tor_log2(4),==, 2);
+ tt_int_op(tor_log2(5),==, 2);
+ tt_int_op(tor_log2(U64_LITERAL(40000000000000000)),==, 55);
+ tt_int_op(tor_log2(UINT64_MAX),==, 63);
/* Test round_to_power_of_2 */
tt_u64_op(round_to_power_of_2(120), ==, 128);
@@ -1373,7 +1425,7 @@ thread_test_func_(void* _s)
/** Run unit tests for threading logic. */
static void
-test_util_threads(void)
+test_util_threads(void *arg)
{
char *s1 = NULL, *s2 = NULL;
int done = 0, timedout = 0;
@@ -1383,12 +1435,7 @@ test_util_threads(void)
tv.tv_sec=0;
tv.tv_usec=100*1000;
#endif
-#ifndef TOR_IS_MULTITHREADED
- /* Skip this test if we aren't threading. We should be threading most
- * everywhere by now. */
- if (1)
- return;
-#endif
+ (void)arg;
thread_test_mutex_ = tor_mutex_new();
thread_test_start1_ = tor_mutex_new();
thread_test_start2_ = tor_mutex_new();
@@ -1426,15 +1473,15 @@ test_util_threads(void)
if (timedout) {
printf("\nTimed out: %d %d", t1_count, t2_count);
- test_assert(strmap_get(thread_test_strmap_, "thread 1"));
- test_assert(strmap_get(thread_test_strmap_, "thread 2"));
- test_assert(!timedout);
+ tt_assert(strmap_get(thread_test_strmap_, "thread 1"));
+ tt_assert(strmap_get(thread_test_strmap_, "thread 2"));
+ tt_assert(!timedout);
}
/* different thread IDs. */
- test_assert(strcmp(strmap_get(thread_test_strmap_, "thread 1"),
+ tt_assert(strcmp(strmap_get(thread_test_strmap_, "thread 1"),
strmap_get(thread_test_strmap_, "thread 2")));
- test_assert(!strcmp(strmap_get(thread_test_strmap_, "thread 1"),
+ tt_assert(!strcmp(strmap_get(thread_test_strmap_, "thread 1"),
strmap_get(thread_test_strmap_, "last to run")) ||
!strcmp(strmap_get(thread_test_strmap_, "thread 2"),
strmap_get(thread_test_strmap_, "last to run")));
@@ -1454,51 +1501,52 @@ test_util_threads(void)
/** Run unit tests for compression functions */
static void
-test_util_gzip(void)
+test_util_gzip(void *arg)
{
char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
const char *ccp2;
size_t len1, len2;
tor_zlib_state_t *state = NULL;
+ (void)arg;
buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
- test_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
+ tt_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
if (is_gzip_supported()) {
- test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
+ tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
GZIP_METHOD));
- test_assert(buf2);
- test_assert(len1 < strlen(buf1));
- test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
+ tt_assert(buf2);
+ tt_assert(len1 < strlen(buf1));
+ tt_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
- test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
+ tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
GZIP_METHOD, 1, LOG_INFO));
- test_assert(buf3);
- test_eq(strlen(buf1) + 1, len2);
- test_streq(buf1, buf3);
+ tt_assert(buf3);
+ tt_int_op(strlen(buf1) + 1,==, len2);
+ tt_str_op(buf1,==, buf3);
tor_free(buf2);
tor_free(buf3);
}
- test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
+ tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
ZLIB_METHOD));
- test_assert(buf2);
- test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
+ tt_assert(buf2);
+ tt_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
- test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
+ tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
ZLIB_METHOD, 1, LOG_INFO));
- test_assert(buf3);
- test_eq(strlen(buf1) + 1, len2);
- test_streq(buf1, buf3);
+ tt_assert(buf3);
+ tt_int_op(strlen(buf1) + 1,==, len2);
+ tt_str_op(buf1,==, buf3);
/* Check whether we can uncompress concatenated, compressed strings. */
tor_free(buf3);
- buf2 = tor_realloc(buf2, len1*2);
+ buf2 = tor_reallocarray(buf2, len1, 2);
memcpy(buf2+len1, buf2, len1);
- test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
+ tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
ZLIB_METHOD, 1, LOG_INFO));
- test_eq((strlen(buf1)+1)*2, len2);
- test_memeq(buf3,
+ tt_int_op((strlen(buf1)+1)*2,==, len2);
+ tt_mem_op(buf3,==,
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
(strlen(buf1)+1)*2);
@@ -1510,7 +1558,7 @@ test_util_gzip(void)
/* Check whether we can uncompress partial strings. */
buf1 =
tor_strdup("String with low redundancy that won't be compressed much.");
- test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
+ tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
ZLIB_METHOD));
tt_assert(len1>16);
/* when we allow an incomplete string, we should succeed.*/
@@ -1536,22 +1584,22 @@ test_util_gzip(void)
len1 = 1024;
ccp2 = "ABCDEFGHIJABCDEFGHIJ";
len2 = 21;
- test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
+ tt_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
== TOR_ZLIB_OK);
- test_eq(0, len2); /* Make sure we compressed it all. */
- test_assert(cp1 > buf1);
+ tt_int_op(0,==, len2); /* Make sure we compressed it all. */
+ tt_assert(cp1 > buf1);
len2 = 0;
cp2 = cp1;
- test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
+ tt_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
== TOR_ZLIB_DONE);
- test_eq(0, len2);
- test_assert(cp1 > cp2); /* Make sure we really added something. */
+ tt_int_op(0,==, len2);
+ tt_assert(cp1 > cp2); /* Make sure we really added something. */
tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
ZLIB_METHOD, 1, LOG_WARN));
- test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
- test_eq(21, len2);
+ tt_str_op(buf3,==,"ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
+ tt_int_op(21,==, len2);
done:
if (state)
@@ -1563,7 +1611,7 @@ test_util_gzip(void)
/** Run unit tests for mmap() wrapper functionality. */
static void
-test_util_mmap(void)
+test_util_mmap(void *arg)
{
char *fname1 = tor_strdup(get_fname("mapped_1"));
char *fname2 = tor_strdup(get_fname("mapped_2"));
@@ -1572,25 +1620,26 @@ test_util_mmap(void)
char *buf = tor_malloc(17000);
tor_mmap_t *mapping = NULL;
+ (void)arg;
crypto_rand(buf, buflen);
mapping = tor_mmap_file(fname1);
- test_assert(! mapping);
+ tt_assert(! mapping);
write_str_to_file(fname1, "Short file.", 1);
mapping = tor_mmap_file(fname1);
- test_assert(mapping);
- test_eq(mapping->size, strlen("Short file."));
- test_streq(mapping->data, "Short file.");
+ tt_assert(mapping);
+ tt_int_op(mapping->size,==, strlen("Short file."));
+ tt_str_op(mapping->data,==, "Short file.");
#ifdef _WIN32
tt_int_op(0, ==, tor_munmap_file(mapping));
mapping = NULL;
- test_assert(unlink(fname1) == 0);
+ tt_assert(unlink(fname1) == 0);
#else
/* make sure we can unlink. */
- test_assert(unlink(fname1) == 0);
- test_streq(mapping->data, "Short file.");
+ tt_assert(unlink(fname1) == 0);
+ tt_str_op(mapping->data,==, "Short file.");
tt_int_op(0, ==, tor_munmap_file(mapping));
mapping = NULL;
#endif
@@ -1598,29 +1647,29 @@ test_util_mmap(void)
/* Now a zero-length file. */
write_str_to_file(fname1, "", 1);
mapping = tor_mmap_file(fname1);
- test_eq_ptr(mapping, NULL);
- test_eq(ERANGE, errno);
+ tt_ptr_op(mapping,==, NULL);
+ tt_int_op(ERANGE,==, errno);
unlink(fname1);
/* Make sure that we fail to map a no-longer-existent file. */
mapping = tor_mmap_file(fname1);
- test_assert(! mapping);
+ tt_assert(! mapping);
/* Now try a big file that stretches across a few pages and isn't aligned */
write_bytes_to_file(fname2, buf, buflen, 1);
mapping = tor_mmap_file(fname2);
- test_assert(mapping);
- test_eq(mapping->size, buflen);
- test_memeq(mapping->data, buf, buflen);
+ tt_assert(mapping);
+ tt_int_op(mapping->size,==, buflen);
+ tt_mem_op(mapping->data,==, buf, buflen);
tt_int_op(0, ==, tor_munmap_file(mapping));
mapping = NULL;
/* Now try a big aligned file. */
write_bytes_to_file(fname3, buf, 16384, 1);
mapping = tor_mmap_file(fname3);
- test_assert(mapping);
- test_eq(mapping->size, 16384);
- test_memeq(mapping->data, buf, 16384);
+ tt_assert(mapping);
+ tt_int_op(mapping->size,==, 16384);
+ tt_mem_op(mapping->data,==, buf, 16384);
tt_int_op(0, ==, tor_munmap_file(mapping));
mapping = NULL;
@@ -1639,17 +1688,18 @@ test_util_mmap(void)
/** Run unit tests for escaping/unescaping data for use by controllers. */
static void
-test_util_control_formats(void)
+test_util_control_formats(void *arg)
{
char *out = NULL;
const char *inp =
"..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
size_t sz;
+ (void)arg;
sz = read_escaped_data(inp, strlen(inp), &out);
- test_streq(out,
+ tt_str_op(out,==,
".This is a test\nof the emergency \n.system.\n\rZ.\n");
- test_eq(sz, strlen(out));
+ tt_int_op(sz,==, strlen(out));
done:
tor_free(out);
@@ -1669,9 +1719,10 @@ test_util_control_formats(void)
} while (0)
static void
-test_util_sscanf(void)
+test_util_sscanf(void *arg)
{
unsigned u1, u2, u3;
+ unsigned long ulng;
char s1[20], s2[10], s3[10], ch;
int r;
long lng1,lng2;
@@ -1679,186 +1730,335 @@ test_util_sscanf(void)
double d1,d2,d3,d4;
/* Simple tests (malformed patterns, literal matching, ...) */
- test_eq(-1, tor_sscanf("123", "%i", &r)); /* %i is not supported */
- test_eq(-1, tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
- test_eq(-1, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
- test_eq(-1, tor_sscanf("prettylongstring", "%999999s", s1));
+ (void)arg;
+ tt_int_op(-1,==, tor_sscanf("123", "%i", &r)); /* %i is not supported */
+ tt_int_op(-1,==,
+ tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
+ tt_int_op(-1,==, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
+ tt_int_op(-1,==, tor_sscanf("prettylongstring", "%999999s", s1));
#if 0
/* GCC thinks these two are illegal. */
test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1));
test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL));
#endif
/* No '%'-strings: always "success" */
- test_eq(0, tor_sscanf("hello world", "hello world"));
- test_eq(0, tor_sscanf("hello world", "good bye"));
+ tt_int_op(0,==, tor_sscanf("hello world", "hello world"));
+ tt_int_op(0,==, tor_sscanf("hello world", "good bye"));
/* Excess data */
- test_eq(0, tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */
- test_eq(0, tor_sscanf(" 3 hello", "%u", &u1));
- test_eq(0, tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
- test_eq(1, tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */
+ tt_int_op(0,==,
+ tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */
+ tt_int_op(0,==, tor_sscanf(" 3 hello", "%u", &u1));
+ tt_int_op(0,==,
+ tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
+ tt_int_op(1,==,
+ tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */
/* Numbers (ie. %u) */
- test_eq(0, tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
- test_eq(1, tor_sscanf("12345", "%u", &u1));
- test_eq(12345u, u1);
- test_eq(1, tor_sscanf("12346 ", "%u", &u1));
- test_eq(12346u, u1);
- test_eq(0, tor_sscanf(" 12347", "%u", &u1));
- test_eq(1, tor_sscanf(" 12348", " %u", &u1));
- test_eq(12348u, u1);
- test_eq(1, tor_sscanf("0", "%u", &u1));
- test_eq(0u, u1);
- test_eq(1, tor_sscanf("0000", "%u", &u2));
- test_eq(0u, u2);
- test_eq(0, tor_sscanf("", "%u", &u1)); /* absent number */
- test_eq(0, tor_sscanf("A", "%u", &u1)); /* bogus number */
- test_eq(0, tor_sscanf("-1", "%u", &u1)); /* negative number */
- test_eq(1, tor_sscanf("4294967295", "%u", &u1)); /* UINT32_MAX should work */
- test_eq(4294967295u, u1);
- test_eq(0, tor_sscanf("4294967296", "%u", &u1)); /* But not at 32 bits */
- test_eq(1, tor_sscanf("4294967296", "%9u", &u1)); /* but parsing only 9... */
- test_eq(429496729u, u1);
+ tt_int_op(0,==,
+ tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
+ tt_int_op(1,==, tor_sscanf("12345", "%u", &u1));
+ tt_int_op(12345u,==, u1);
+ tt_int_op(1,==, tor_sscanf("12346 ", "%u", &u1));
+ tt_int_op(12346u,==, u1);
+ tt_int_op(0,==, tor_sscanf(" 12347", "%u", &u1));
+ tt_int_op(1,==, tor_sscanf(" 12348", " %u", &u1));
+ tt_int_op(12348u,==, u1);
+ tt_int_op(1,==, tor_sscanf("0", "%u", &u1));
+ tt_int_op(0u,==, u1);
+ tt_int_op(1,==, tor_sscanf("0000", "%u", &u2));
+ tt_int_op(0u,==, u2);
+ tt_int_op(0,==, tor_sscanf("", "%u", &u1)); /* absent number */
+ tt_int_op(0,==, tor_sscanf("A", "%u", &u1)); /* bogus number */
+ tt_int_op(0,==, tor_sscanf("-1", "%u", &u1)); /* negative number */
/* Numbers with size (eg. %2u) */
- test_eq(0, tor_sscanf("-1", "%2u", &u1));
- test_eq(2, tor_sscanf("123456", "%2u%u", &u1, &u2));
- test_eq(12u, u1);
- test_eq(3456u, u2);
- test_eq(1, tor_sscanf("123456", "%8u", &u1));
- test_eq(123456u, u1);
- test_eq(1, tor_sscanf("123457 ", "%8u", &u1));
- test_eq(123457u, u1);
- test_eq(0, tor_sscanf(" 123456", "%8u", &u1));
- test_eq(3, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
- test_eq(12u, u1);
- test_eq(3u, u2);
- test_eq(456u, u3);
- test_eq(3, tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
- test_eq(67u, u1);
- test_eq(8u, u2);
- test_eq(99u, u3);
+ tt_int_op(0,==, tor_sscanf("-1", "%2u", &u1));
+ tt_int_op(2,==, tor_sscanf("123456", "%2u%u", &u1, &u2));
+ tt_int_op(12u,==, u1);
+ tt_int_op(3456u,==, u2);
+ tt_int_op(1,==, tor_sscanf("123456", "%8u", &u1));
+ tt_int_op(123456u,==, u1);
+ tt_int_op(1,==, tor_sscanf("123457 ", "%8u", &u1));
+ tt_int_op(123457u,==, u1);
+ tt_int_op(0,==, tor_sscanf(" 123456", "%8u", &u1));
+ tt_int_op(3,==, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
+ tt_int_op(12u,==, u1);
+ tt_int_op(3u,==, u2);
+ tt_int_op(456u,==, u3);
+ tt_int_op(3,==,
+ tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
+ tt_int_op(67u,==, u1);
+ tt_int_op(8u,==, u2);
+ tt_int_op(99u,==, u3);
/* %u does not match space.*/
- test_eq(2, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
- test_eq(12u, u1);
- test_eq(3u, u2);
+ tt_int_op(2,==, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
+ tt_int_op(12u,==, u1);
+ tt_int_op(3u,==, u2);
/* %u does not match negative numbers. */
- test_eq(2, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
- test_eq(67u, u1);
- test_eq(8u, u2);
+ tt_int_op(2,==, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
+ tt_int_op(67u,==, u1);
+ tt_int_op(8u,==, u2);
/* Arbitrary amounts of 0-padding are okay */
- test_eq(3, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
+ tt_int_op(3,==, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
&u1, &u2, &u3));
- test_eq(12u, u1);
- test_eq(3u, u2);
- test_eq(99u, u3);
+ tt_int_op(12u,==, u1);
+ tt_int_op(3u,==, u2);
+ tt_int_op(99u,==, u3);
/* Hex (ie. %x) */
- test_eq(3, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
- test_eq(0x1234, u1);
- test_eq(0x2ABCDEF, u2);
- test_eq(0xFF, u3);
+ tt_int_op(3,==, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
+ tt_int_op(0x1234,==, u1);
+ tt_int_op(0x2ABCDEF,==, u2);
+ tt_int_op(0xFF,==, u3);
/* Width works on %x */
- test_eq(3, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
- test_eq(0xf00d, u1);
- test_eq(0xcafe, u2);
- test_eq(444, u3);
+ tt_int_op(3,==, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
+ tt_int_op(0xf00d,==, u1);
+ tt_int_op(0xcafe,==, u2);
+ tt_int_op(444,==, u3);
/* Literal '%' (ie. '%%') */
- test_eq(1, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
- test_eq(99, u1);
- test_eq(0, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1));
- test_eq(1, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1));
- test_eq(2, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1));
- test_eq(99, u1);
- test_streq(s1, "fresh");
- test_eq(1, tor_sscanf("% boo", "%% %3s", s1));
- test_streq("boo", s1);
+ tt_int_op(1,==, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
+ tt_int_op(99,==, u1);
+ tt_int_op(0,==, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1));
+ tt_int_op(1,==, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1));
+ tt_int_op(2,==, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1));
+ tt_int_op(99,==, u1);
+ tt_str_op(s1,==, "fresh");
+ tt_int_op(1,==, tor_sscanf("% boo", "%% %3s", s1));
+ tt_str_op("boo",==, s1);
/* Strings (ie. %s) */
- test_eq(2, tor_sscanf("hello", "%3s%7s", s1, s2));
- test_streq(s1, "hel");
- test_streq(s2, "lo");
- test_eq(2, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
- test_streq(s3, "WD");
- test_eq(40, u1);
- test_eq(2, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
- test_streq(s3, "WD4");
- test_eq(0, u1);
- test_eq(2, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
- test_eq(76, u1);
- test_streq(s1, "trombones");
- test_eq(1, tor_sscanf("prettylongstring", "%999s", s1));
- test_streq(s1, "prettylongstring");
+ tt_int_op(2,==, tor_sscanf("hello", "%3s%7s", s1, s2));
+ tt_str_op(s1,==, "hel");
+ tt_str_op(s2,==, "lo");
+ tt_int_op(2,==, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
+ tt_str_op(s3,==, "WD");
+ tt_int_op(40,==, u1);
+ tt_int_op(2,==, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
+ tt_str_op(s3,==, "WD4");
+ tt_int_op(0,==, u1);
+ tt_int_op(2,==, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
+ tt_int_op(76,==, u1);
+ tt_str_op(s1,==, "trombones");
+ tt_int_op(1,==, tor_sscanf("prettylongstring", "%999s", s1));
+ tt_str_op(s1,==, "prettylongstring");
/* %s doesn't eat spaces */
- test_eq(2, tor_sscanf("hello world", "%9s %9s", s1, s2));
- test_streq(s1, "hello");
- test_streq(s2, "world");
- test_eq(2, tor_sscanf("bye world?", "%9s %9s", s1, s2));
- test_streq(s1, "bye");
- test_streq(s2, "");
- test_eq(3, tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
- test_streq(s1, "hi");
- test_streq(s2, "");
- test_streq(s3, "");
-
- test_eq(3, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
- test_eq(4, tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
- test_eq(' ', ch);
+ tt_int_op(2,==, tor_sscanf("hello world", "%9s %9s", s1, s2));
+ tt_str_op(s1,==, "hello");
+ tt_str_op(s2,==, "world");
+ tt_int_op(2,==, tor_sscanf("bye world?", "%9s %9s", s1, s2));
+ tt_str_op(s1,==, "bye");
+ tt_str_op(s2,==, "");
+ tt_int_op(3,==,
+ tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
+ tt_str_op(s1,==, "hi");
+ tt_str_op(s2,==, "");
+ tt_str_op(s3,==, "");
+
+ tt_int_op(3,==, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
+ tt_int_op(4,==,
+ tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
+ tt_int_op(' ',==, ch);
r = tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1, &lng1, &int2);
- test_eq(r,3);
- test_eq(int1, 12345);
- test_eq(lng1, -67890);
- test_eq(int2, -1);
+ tt_int_op(r,==, 3);
+ tt_int_op(int1,==, 12345);
+ tt_int_op(lng1,==, -67890);
+ tt_int_op(int2,==, -1);
#if SIZEOF_INT == 4
+ /* %u */
+ /* UINT32_MAX should work */
+ tt_int_op(1,==, tor_sscanf("4294967295", "%u", &u1));
+ tt_int_op(4294967295U,==, u1);
+
+ /* But UINT32_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("4294967296", "%u", &u1));
+ /* but parsing only 9... */
+ tt_int_op(1,==, tor_sscanf("4294967296", "%9u", &u1));
+ tt_int_op(429496729U,==, u1);
+
+ /* %x */
+ /* UINT32_MAX should work */
+ tt_int_op(1,==, tor_sscanf("FFFFFFFF", "%x", &u1));
+ tt_int_op(0xFFFFFFFF,==, u1);
+
+ /* But UINT32_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("100000000", "%x", &u1));
+
+ /* %d */
+ /* INT32_MIN and INT32_MAX should work */
r = tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1, &int2);
- test_eq(r,2);
- test_eq(int1, -2147483647-1);
- test_eq(int2, 2147483647);
+ tt_int_op(r,==, 2);
+ tt_int_op(int1,==, -2147483647 - 1);
+ tt_int_op(int2,==, 2147483647);
+
+ /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
+ r = tor_sscanf("-2147483649.", "%d.", &int1);
+ tt_int_op(r,==, 0);
- r = tor_sscanf("-2147483679.", "%d.", &int1);
- test_eq(r,0);
+ r = tor_sscanf("2147483648.", "%d.", &int1);
+ tt_int_op(r,==, 0);
+
+ /* and the first failure stops further processing */
+ r = tor_sscanf("-2147483648. 2147483648.",
+ "%d. %d.", &int1, &int2);
+ tt_int_op(r,==, 1);
- r = tor_sscanf("2147483678.", "%d.", &int1);
- test_eq(r,0);
+ r = tor_sscanf("-2147483649. 2147483647.",
+ "%d. %d.", &int1, &int2);
+ tt_int_op(r,==, 0);
+
+ r = tor_sscanf("2147483648. -2147483649.",
+ "%d. %d.", &int1, &int2);
+ tt_int_op(r,==, 0);
#elif SIZEOF_INT == 8
+ /* %u */
+ /* UINT64_MAX should work */
+ tt_int_op(1,==, tor_sscanf("18446744073709551615", "%u", &u1));
+ tt_int_op(18446744073709551615U,==, u1);
+
+ /* But UINT64_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("18446744073709551616", "%u", &u1));
+ /* but parsing only 19... */
+ tt_int_op(1,==, tor_sscanf("18446744073709551616", "%19u", &u1));
+ tt_int_op(1844674407370955161U,==, u1);
+
+ /* %x */
+ /* UINT64_MAX should work */
+ tt_int_op(1,==, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1));
+ tt_int_op(0xFFFFFFFFFFFFFFFF,==, u1);
+
+ /* But UINT64_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("10000000000000000", "%x", &u1));
+
+ /* %d */
+ /* INT64_MIN and INT64_MAX should work */
r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
"%d. %d.", &int1, &int2);
- test_eq(r,2);
- test_eq(int1, -9223372036854775807-1);
- test_eq(int2, 9223372036854775807);
+ tt_int_op(r,==, 2);
+ tt_int_op(int1,==, -9223372036854775807 - 1);
+ tt_int_op(int2,==, 9223372036854775807);
+ /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
r = tor_sscanf("-9223372036854775809.", "%d.", &int1);
- test_eq(r,0);
+ tt_int_op(r,==, 0);
r = tor_sscanf("9223372036854775808.", "%d.", &int1);
- test_eq(r,0);
+ tt_int_op(r,==, 0);
+
+ /* and the first failure stops further processing */
+ r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
+ "%d. %d.", &int1, &int2);
+ tt_int_op(r,==, 1);
+
+ r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
+ "%d. %d.", &int1, &int2);
+ tt_int_op(r,==, 0);
+
+ r = tor_sscanf("9223372036854775808. -9223372036854775809.",
+ "%d. %d.", &int1, &int2);
+ tt_int_op(r,==, 0);
#endif
#if SIZEOF_LONG == 4
+ /* %lu */
+ /* UINT32_MAX should work */
+ tt_int_op(1,==, tor_sscanf("4294967295", "%lu", &ulng));
+ tt_int_op(4294967295UL,==, ulng);
+
+ /* But UINT32_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("4294967296", "%lu", &ulng));
+ /* but parsing only 9... */
+ tt_int_op(1,==, tor_sscanf("4294967296", "%9lu", &ulng));
+ tt_int_op(429496729UL,==, ulng);
+
+ /* %lx */
+ /* UINT32_MAX should work */
+ tt_int_op(1,==, tor_sscanf("FFFFFFFF", "%lx", &ulng));
+ tt_int_op(0xFFFFFFFFUL,==, ulng);
+
+ /* But UINT32_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("100000000", "%lx", &ulng));
+
+ /* %ld */
+ /* INT32_MIN and INT32_MAX should work */
r = tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1, &lng2);
- test_eq(r,2);
- test_eq(lng1, -2147483647 - 1);
- test_eq(lng2, 2147483647);
+ tt_int_op(r,==, 2);
+ tt_int_op(lng1,==, -2147483647L - 1L);
+ tt_int_op(lng2,==, 2147483647L);
+
+ /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
+ r = tor_sscanf("-2147483649.", "%ld.", &lng1);
+ tt_int_op(r,==, 0);
+
+ r = tor_sscanf("2147483648.", "%ld.", &lng1);
+ tt_int_op(r,==, 0);
+
+ /* and the first failure stops further processing */
+ r = tor_sscanf("-2147483648. 2147483648.",
+ "%ld. %ld.", &lng1, &lng2);
+ tt_int_op(r,==, 1);
+
+ r = tor_sscanf("-2147483649. 2147483647.",
+ "%ld. %ld.", &lng1, &lng2);
+ tt_int_op(r,==, 0);
+
+ r = tor_sscanf("2147483648. -2147483649.",
+ "%ld. %ld.", &lng1, &lng2);
+ tt_int_op(r,==, 0);
#elif SIZEOF_LONG == 8
+ /* %lu */
+ /* UINT64_MAX should work */
+ tt_int_op(1,==, tor_sscanf("18446744073709551615", "%lu", &ulng));
+ tt_int_op(18446744073709551615UL,==, ulng);
+
+ /* But UINT64_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("18446744073709551616", "%lu", &ulng));
+ /* but parsing only 19... */
+ tt_int_op(1,==, tor_sscanf("18446744073709551616", "%19lu", &ulng));
+ tt_int_op(1844674407370955161UL,==, ulng);
+
+ /* %lx */
+ /* UINT64_MAX should work */
+ tt_int_op(1,==, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng));
+ tt_int_op(0xFFFFFFFFFFFFFFFFUL,==, ulng);
+
+ /* But UINT64_MAX + 1 shouldn't work */
+ tt_int_op(0,==, tor_sscanf("10000000000000000", "%lx", &ulng));
+
+ /* %ld */
+ /* INT64_MIN and INT64_MAX should work */
r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
"%ld. %ld.", &lng1, &lng2);
- test_eq(r,2);
- test_eq(lng1, -9223372036854775807L - 1);
- test_eq(lng2, 9223372036854775807L);
+ tt_int_op(r,==, 2);
+ tt_int_op(lng1,==, -9223372036854775807L - 1L);
+ tt_int_op(lng2,==, 9223372036854775807L);
+
+ /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
+ r = tor_sscanf("-9223372036854775809.", "%ld.", &lng1);
+ tt_int_op(r,==, 0);
+
+ r = tor_sscanf("9223372036854775808.", "%ld.", &lng1);
+ tt_int_op(r,==, 0);
+ /* and the first failure stops further processing */
r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
"%ld. %ld.", &lng1, &lng2);
- test_eq(r,1);
- r = tor_sscanf("-9223372036854775809. 9223372036854775808.",
+ tt_int_op(r,==, 1);
+
+ r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
+ "%ld. %ld.", &lng1, &lng2);
+ tt_int_op(r,==, 0);
+
+ r = tor_sscanf("9223372036854775808. -9223372036854775809.",
"%ld. %ld.", &lng1, &lng2);
- test_eq(r,0);
+ tt_int_op(r,==, 0);
#endif
r = tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
"%lf %lf %lf %lf", &d1,&d2,&d3,&d4);
- test_eq(r,4);
+ tt_int_op(r,==, 4);
test_feq(d1, 123.456);
test_feq(d2, .000007);
test_feq(d3, -900123123.2000787);
@@ -1869,33 +2069,34 @@ test_util_sscanf(void)
}
static void
-test_util_path_is_relative(void)
+test_util_path_is_relative(void *arg)
{
/* OS-independent tests */
- test_eq(1, path_is_relative(""));
- test_eq(1, path_is_relative("dir"));
- test_eq(1, path_is_relative("dir/"));
- test_eq(1, path_is_relative("./dir"));
- test_eq(1, path_is_relative("../dir"));
+ (void)arg;
+ tt_int_op(1,==, path_is_relative(""));
+ tt_int_op(1,==, path_is_relative("dir"));
+ tt_int_op(1,==, path_is_relative("dir/"));
+ tt_int_op(1,==, path_is_relative("./dir"));
+ tt_int_op(1,==, path_is_relative("../dir"));
- test_eq(0, path_is_relative("/"));
- test_eq(0, path_is_relative("/dir"));
- test_eq(0, path_is_relative("/dir/"));
+ tt_int_op(0,==, path_is_relative("/"));
+ tt_int_op(0,==, path_is_relative("/dir"));
+ tt_int_op(0,==, path_is_relative("/dir/"));
/* Windows */
#ifdef _WIN32
/* I don't have Windows so I can't test this, hence the "#ifdef
0". These are tests that look useful, so please try to get them
running and uncomment if it all works as it should */
- test_eq(1, path_is_relative("dir"));
- test_eq(1, path_is_relative("dir\\"));
- test_eq(1, path_is_relative("dir\\a:"));
- test_eq(1, path_is_relative("dir\\a:\\"));
- test_eq(1, path_is_relative("http:\\dir"));
-
- test_eq(0, path_is_relative("\\dir"));
- test_eq(0, path_is_relative("a:\\dir"));
- test_eq(0, path_is_relative("z:\\dir"));
+ tt_int_op(1,==, path_is_relative("dir"));
+ tt_int_op(1,==, path_is_relative("dir\\"));
+ tt_int_op(1,==, path_is_relative("dir\\a:"));
+ tt_int_op(1,==, path_is_relative("dir\\a:\\"));
+ tt_int_op(1,==, path_is_relative("http:\\dir"));
+
+ tt_int_op(0,==, path_is_relative("\\dir"));
+ tt_int_op(0,==, path_is_relative("a:\\dir"));
+ tt_int_op(0,==, path_is_relative("z:\\dir"));
#endif
done:
@@ -1906,25 +2107,26 @@ test_util_path_is_relative(void)
/** Run unittests for memory pool allocator */
static void
-test_util_mempool(void)
+test_util_mempool(void *arg)
{
mp_pool_t *pool = NULL;
smartlist_t *allocated = NULL;
int i;
+ (void)arg;
pool = mp_pool_new(1, 100);
- test_assert(pool);
- test_assert(pool->new_chunk_capacity >= 100);
- test_assert(pool->item_alloc_size >= sizeof(void*)+1);
+ tt_assert(pool);
+ tt_assert(pool->new_chunk_capacity >= 100);
+ tt_assert(pool->item_alloc_size >= sizeof(void*)+1);
mp_pool_destroy(pool);
pool = NULL;
pool = mp_pool_new(241, 2500);
- test_assert(pool);
- test_assert(pool->new_chunk_capacity >= 10);
- test_assert(pool->item_alloc_size >= sizeof(void*)+241);
- test_eq(pool->item_alloc_size & 0x03, 0);
- test_assert(pool->new_chunk_capacity < 60);
+ tt_assert(pool);
+ tt_assert(pool->new_chunk_capacity >= 10);
+ tt_assert(pool->item_alloc_size >= sizeof(void*)+241);
+ tt_int_op(pool->item_alloc_size & 0x03,==, 0);
+ tt_assert(pool->new_chunk_capacity < 60);
allocated = smartlist_new();
for (i = 0; i < 20000; ++i) {
@@ -1966,39 +2168,40 @@ test_util_mempool(void)
/** Run unittests for memory area allocator */
static void
-test_util_memarea(void)
+test_util_memarea(void *arg)
{
memarea_t *area = memarea_new();
char *p1, *p2, *p3, *p1_orig;
void *malloced_ptr = NULL;
int i;
- test_assert(area);
+ (void)arg;
+ tt_assert(area);
p1_orig = p1 = memarea_alloc(area,64);
p2 = memarea_alloc_zero(area,52);
p3 = memarea_alloc(area,11);
- test_assert(memarea_owns_ptr(area, p1));
- test_assert(memarea_owns_ptr(area, p2));
- test_assert(memarea_owns_ptr(area, p3));
+ tt_assert(memarea_owns_ptr(area, p1));
+ tt_assert(memarea_owns_ptr(area, p2));
+ tt_assert(memarea_owns_ptr(area, p3));
/* Make sure we left enough space. */
- test_assert(p1+64 <= p2);
- test_assert(p2+52 <= p3);
+ tt_assert(p1+64 <= p2);
+ tt_assert(p2+52 <= p3);
/* Make sure we aligned. */
- test_eq(((uintptr_t)p1) % sizeof(void*), 0);
- test_eq(((uintptr_t)p2) % sizeof(void*), 0);
- test_eq(((uintptr_t)p3) % sizeof(void*), 0);
- test_assert(!memarea_owns_ptr(area, p3+8192));
- test_assert(!memarea_owns_ptr(area, p3+30));
- test_assert(tor_mem_is_zero(p2, 52));
+ tt_int_op(((uintptr_t)p1) % sizeof(void*),==, 0);
+ tt_int_op(((uintptr_t)p2) % sizeof(void*),==, 0);
+ tt_int_op(((uintptr_t)p3) % sizeof(void*),==, 0);
+ tt_assert(!memarea_owns_ptr(area, p3+8192));
+ tt_assert(!memarea_owns_ptr(area, p3+30));
+ tt_assert(tor_mem_is_zero(p2, 52));
/* Make sure we don't overalign. */
p1 = memarea_alloc(area, 1);
p2 = memarea_alloc(area, 1);
- test_eq_ptr(p1+sizeof(void*), p2);
+ tt_ptr_op(p1+sizeof(void*),==, p2);
{
malloced_ptr = tor_malloc(64);
- test_assert(!memarea_owns_ptr(area, malloced_ptr));
+ tt_assert(!memarea_owns_ptr(area, malloced_ptr));
tor_free(malloced_ptr);
}
@@ -2007,18 +2210,18 @@ test_util_memarea(void)
malloced_ptr = tor_malloc(64);
crypto_rand((char*)malloced_ptr, 64);
p1 = memarea_memdup(area, malloced_ptr, 64);
- test_assert(p1 != malloced_ptr);
- test_memeq(p1, malloced_ptr, 64);
+ tt_assert(p1 != malloced_ptr);
+ tt_mem_op(p1,==, malloced_ptr, 64);
tor_free(malloced_ptr);
}
/* memarea_strdup. */
p1 = memarea_strdup(area,"");
p2 = memarea_strdup(area, "abcd");
- test_assert(p1);
- test_assert(p2);
- test_streq(p1, "");
- test_streq(p2, "abcd");
+ tt_assert(p1);
+ tt_assert(p2);
+ tt_str_op(p1,==, "");
+ tt_str_op(p2,==, "abcd");
/* memarea_strndup. */
{
@@ -2027,33 +2230,33 @@ test_util_memarea(void)
size_t len = strlen(s);
p1 = memarea_strndup(area, s, 1000);
p2 = memarea_strndup(area, s, 10);
- test_streq(p1, s);
- test_assert(p2 >= p1 + len + 1);
- test_memeq(s, p2, 10);
- test_eq(p2[10], '\0');
+ tt_str_op(p1,==, s);
+ tt_assert(p2 >= p1 + len + 1);
+ tt_mem_op(s,==, p2, 10);
+ tt_int_op(p2[10],==, '\0');
p3 = memarea_strndup(area, s, len);
- test_streq(p3, s);
+ tt_str_op(p3,==, s);
p3 = memarea_strndup(area, s, len-1);
- test_memeq(s, p3, len-1);
- test_eq(p3[len-1], '\0');
+ tt_mem_op(s,==, p3, len-1);
+ tt_int_op(p3[len-1],==, '\0');
}
memarea_clear(area);
p1 = memarea_alloc(area, 1);
- test_eq_ptr(p1, p1_orig);
+ tt_ptr_op(p1,==, p1_orig);
memarea_clear(area);
/* Check for running over an area's size. */
for (i = 0; i < 512; ++i) {
p1 = memarea_alloc(area, crypto_rand_int(5)+1);
- test_assert(memarea_owns_ptr(area, p1));
+ tt_assert(memarea_owns_ptr(area, p1));
}
memarea_assert_ok(area);
/* Make sure we can allocate a too-big object. */
p1 = memarea_alloc_zero(area, 9000);
p2 = memarea_alloc_zero(area, 16);
- test_assert(memarea_owns_ptr(area, p1));
- test_assert(memarea_owns_ptr(area, p2));
+ tt_assert(memarea_owns_ptr(area, p1));
+ tt_assert(memarea_owns_ptr(area, p2));
done:
memarea_drop_all(area);
@@ -2063,31 +2266,32 @@ test_util_memarea(void)
/** Run unit tests for utility functions to get file names relative to
* the data directory. */
static void
-test_util_datadir(void)
+test_util_datadir(void *arg)
{
char buf[1024];
char *f = NULL;
char *temp_dir = NULL;
+ (void)arg;
temp_dir = get_datadir_fname(NULL);
f = get_datadir_fname("state");
tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
- test_streq(f, buf);
+ tt_str_op(f,==, buf);
tor_free(f);
f = get_datadir_fname2("cache", "thingy");
tor_snprintf(buf, sizeof(buf),
"%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
- test_streq(f, buf);
+ tt_str_op(f,==, buf);
tor_free(f);
f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
tor_snprintf(buf, sizeof(buf),
"%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
- test_streq(f, buf);
+ tt_str_op(f,==, buf);
tor_free(f);
f = get_datadir_fname_suffix("cache", ".foo");
tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
temp_dir);
- test_streq(f, buf);
+ tt_str_op(f,==, buf);
done:
tor_free(f);
@@ -2095,13 +2299,14 @@ test_util_datadir(void)
}
static void
-test_util_strtok(void)
+test_util_strtok(void *arg)
{
char buf[128];
char buf2[128];
int i;
char *cp1, *cp2;
+ (void)arg;
for (i = 0; i < 3; i++) {
const char *pad1="", *pad2="";
switch (i) {
@@ -2118,8 +2323,8 @@ test_util_strtok(void)
}
tor_snprintf(buf, sizeof(buf), "%s", pad1);
tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
- test_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1));
- test_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2));
+ tt_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1));
+ tt_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2));
tor_snprintf(buf, sizeof(buf),
"%sGraved on the dark in gestures of descent%s", pad1, pad1);
@@ -2127,43 +2332,43 @@ test_util_strtok(void)
"%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
/* -- "Year's End", Richard Wilbur */
- test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
- test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
+ tt_str_op("Graved",==, tor_strtok_r_impl(buf, " ", &cp1));
+ tt_str_op("they",==, tor_strtok_r_impl(buf2, ".!..;!", &cp2));
#define S1() tor_strtok_r_impl(NULL, " ", &cp1)
#define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
- test_streq("on", S1());
- test_streq("the", S1());
- test_streq("dark", S1());
- test_streq("seemed", S2());
- test_streq("their", S2());
- test_streq("own", S2());
- test_streq("in", S1());
- test_streq("gestures", S1());
- test_streq("of", S1());
- test_streq("most", S2());
- test_streq("perfect", S2());
- test_streq("descent", S1());
- test_streq("monument", S2());
- test_eq_ptr(NULL, S1());
- test_eq_ptr(NULL, S2());
+ tt_str_op("on",==, S1());
+ tt_str_op("the",==, S1());
+ tt_str_op("dark",==, S1());
+ tt_str_op("seemed",==, S2());
+ tt_str_op("their",==, S2());
+ tt_str_op("own",==, S2());
+ tt_str_op("in",==, S1());
+ tt_str_op("gestures",==, S1());
+ tt_str_op("of",==, S1());
+ tt_str_op("most",==, S2());
+ tt_str_op("perfect",==, S2());
+ tt_str_op("descent",==, S1());
+ tt_str_op("monument",==, S2());
+ tt_ptr_op(NULL,==, S1());
+ tt_ptr_op(NULL,==, S2());
}
buf[0] = 0;
- test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
- test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1));
+ tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, " ", &cp1));
+ tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, "!", &cp1));
strlcpy(buf, "Howdy!", sizeof(buf));
- test_streq("Howdy", tor_strtok_r_impl(buf, "!", &cp1));
- test_eq_ptr(NULL, tor_strtok_r_impl(NULL, "!", &cp1));
+ tt_str_op("Howdy",==, tor_strtok_r_impl(buf, "!", &cp1));
+ tt_ptr_op(NULL,==, tor_strtok_r_impl(NULL, "!", &cp1));
strlcpy(buf, " ", sizeof(buf));
- test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
+ tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, " ", &cp1));
strlcpy(buf, " ", sizeof(buf));
- test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
+ tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, " ", &cp1));
strlcpy(buf, "something ", sizeof(buf));
- test_streq("something", tor_strtok_r_impl(buf, " ", &cp1));
- test_eq_ptr(NULL, tor_strtok_r_impl(NULL, ";", &cp1));
+ tt_str_op("something",==, tor_strtok_r_impl(buf, " ", &cp1));
+ tt_ptr_op(NULL,==, tor_strtok_r_impl(NULL, ";", &cp1));
done:
;
}
@@ -2183,23 +2388,24 @@ test_util_find_str_at_start_of_line(void *ptr)
(void)ptr;
- test_eq_ptr(long_string, find_str_at_start_of_line(long_string, ""));
- test_eq_ptr(NULL, find_str_at_start_of_line(short_string, "nonsense"));
- test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "nonsense"));
- test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "\n"));
- test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "how "));
- test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "kitty"));
- test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "h"));
- test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "how"));
- test_eq_ptr(line2, find_str_at_start_of_line(long_string, "he"));
- test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hell"));
- test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello k"));
- test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\n"));
- test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\nt"));
- test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third"));
- test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third line"));
- test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "third line\n"));
- test_eq_ptr(short_line2, find_str_at_start_of_line(short_string,
+ tt_ptr_op(long_string,==, find_str_at_start_of_line(long_string, ""));
+ tt_ptr_op(NULL,==, find_str_at_start_of_line(short_string, "nonsense"));
+ tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "nonsense"));
+ tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "\n"));
+ tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "how "));
+ tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "kitty"));
+ tt_ptr_op(long_string,==, find_str_at_start_of_line(long_string, "h"));
+ tt_ptr_op(long_string,==, find_str_at_start_of_line(long_string, "how"));
+ tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "he"));
+ tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "hell"));
+ tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "hello k"));
+ tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "hello kitty\n"));
+ tt_ptr_op(line2,==,
+ find_str_at_start_of_line(long_string, "hello kitty\nt"));
+ tt_ptr_op(line3,==, find_str_at_start_of_line(long_string, "third"));
+ tt_ptr_op(line3,==, find_str_at_start_of_line(long_string, "third line"));
+ tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "third line\n"));
+ tt_ptr_op(short_line2,==, find_str_at_start_of_line(short_string,
"second line\n"));
done:
;
@@ -2210,25 +2416,25 @@ test_util_string_is_C_identifier(void *ptr)
{
(void)ptr;
- test_eq(1, string_is_C_identifier("string_is_C_identifier"));
- test_eq(1, string_is_C_identifier("_string_is_C_identifier"));
- test_eq(1, string_is_C_identifier("_"));
- test_eq(1, string_is_C_identifier("i"));
- test_eq(1, string_is_C_identifier("_____"));
- test_eq(1, string_is_C_identifier("__00__"));
- test_eq(1, string_is_C_identifier("__init__"));
- test_eq(1, string_is_C_identifier("_0"));
- test_eq(1, string_is_C_identifier("_0string_is_C_identifier"));
- test_eq(1, string_is_C_identifier("_0"));
-
- test_eq(0, string_is_C_identifier("0_string_is_C_identifier"));
- test_eq(0, string_is_C_identifier("0"));
- test_eq(0, string_is_C_identifier(""));
- test_eq(0, string_is_C_identifier(";"));
- test_eq(0, string_is_C_identifier("i;"));
- test_eq(0, string_is_C_identifier("_;"));
- test_eq(0, string_is_C_identifier("í"));
- test_eq(0, string_is_C_identifier("ñ"));
+ tt_int_op(1,==, string_is_C_identifier("string_is_C_identifier"));
+ tt_int_op(1,==, string_is_C_identifier("_string_is_C_identifier"));
+ tt_int_op(1,==, string_is_C_identifier("_"));
+ tt_int_op(1,==, string_is_C_identifier("i"));
+ tt_int_op(1,==, string_is_C_identifier("_____"));
+ tt_int_op(1,==, string_is_C_identifier("__00__"));
+ tt_int_op(1,==, string_is_C_identifier("__init__"));
+ tt_int_op(1,==, string_is_C_identifier("_0"));
+ tt_int_op(1,==, string_is_C_identifier("_0string_is_C_identifier"));
+ tt_int_op(1,==, string_is_C_identifier("_0"));
+
+ tt_int_op(0,==, string_is_C_identifier("0_string_is_C_identifier"));
+ tt_int_op(0,==, string_is_C_identifier("0"));
+ tt_int_op(0,==, string_is_C_identifier(""));
+ tt_int_op(0,==, string_is_C_identifier(";"));
+ tt_int_op(0,==, string_is_C_identifier("i;"));
+ tt_int_op(0,==, string_is_C_identifier("_;"));
+ tt_int_op(0,==, string_is_C_identifier("í"));
+ tt_int_op(0,==, string_is_C_identifier("ñ"));
done:
;
@@ -2245,48 +2451,48 @@ test_util_asprintf(void *ptr)
/* simple string */
r = tor_asprintf(&cp, "simple string 100%% safe");
- test_assert(cp);
- test_streq("simple string 100% safe", cp);
- test_eq(strlen(cp), r);
+ tt_assert(cp);
+ tt_str_op("simple string 100% safe",==, cp);
+ tt_int_op(strlen(cp),==, r);
tor_free(cp);
/* empty string */
r = tor_asprintf(&cp, "%s", "");
- test_assert(cp);
- test_streq("", cp);
- test_eq(strlen(cp), r);
+ tt_assert(cp);
+ tt_str_op("",==, cp);
+ tt_int_op(strlen(cp),==, r);
tor_free(cp);
/* numbers (%i) */
r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
- test_assert(cp);
- test_streq("I like numbers--1, 2, etc.", cp);
- test_eq(strlen(cp), r);
+ tt_assert(cp);
+ tt_str_op("I like numbers--1, 2, etc.",==, cp);
+ tt_int_op(strlen(cp),==, r);
/* don't free cp; next test uses it. */
/* numbers (%d) */
r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
- test_assert(cp2);
- test_eq(strlen(cp2), r);
- test_streq("First=101, Second=202", cp2);
- test_assert(cp != cp2);
+ tt_assert(cp2);
+ tt_int_op(strlen(cp2),==, r);
+ tt_str_op("First=101, Second=202",==, cp2);
+ tt_assert(cp != cp2);
tor_free(cp);
tor_free(cp2);
/* Glass-box test: a string exactly 128 characters long. */
r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
- test_assert(cp);
- test_eq(128, r);
- test_assert(cp[128] == '\0');
- test_streq("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM, cp);
+ tt_assert(cp);
+ tt_int_op(128,==, r);
+ tt_int_op(cp[128], ==, '\0');
+ tt_str_op("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM,==, cp);
tor_free(cp);
/* String longer than 128 characters */
r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
- test_assert(cp);
- test_eq(strlen(cp), r);
- test_streq("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM, cp);
+ tt_assert(cp);
+ tt_int_op(strlen(cp),==, r);
+ tt_str_op("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM,==, cp);
done:
tor_free(cp);
@@ -2307,9 +2513,9 @@ test_util_listdir(void *ptr)
dir1 = tor_strdup(get_fname("some-directory"));
dirname = tor_strdup(get_fname(NULL));
- test_eq(0, write_str_to_file(fname1, "X\n", 0));
- test_eq(0, write_str_to_file(fname2, "Y\n", 0));
- test_eq(0, write_str_to_file(fname3, "Z\n", 0));
+ tt_int_op(0,==, write_str_to_file(fname1, "X\n", 0));
+ tt_int_op(0,==, write_str_to_file(fname2, "Y\n", 0));
+ tt_int_op(0,==, write_str_to_file(fname3, "Z\n", 0));
#ifdef _WIN32
r = mkdir(dir1);
#else
@@ -2322,15 +2528,15 @@ test_util_listdir(void *ptr)
}
dir_contents = tor_listdir(dirname);
- test_assert(dir_contents);
+ tt_assert(dir_contents);
/* make sure that each filename is listed. */
- test_assert(smartlist_contains_string_case(dir_contents, "hopscotch"));
- test_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg"));
- test_assert(smartlist_contains_string_case(dir_contents, ".hidden-file"));
- test_assert(smartlist_contains_string_case(dir_contents, "some-directory"));
+ tt_assert(smartlist_contains_string_case(dir_contents, "hopscotch"));
+ tt_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg"));
+ tt_assert(smartlist_contains_string_case(dir_contents, ".hidden-file"));
+ tt_assert(smartlist_contains_string_case(dir_contents, "some-directory"));
- test_assert(!smartlist_contains_string(dir_contents, "."));
- test_assert(!smartlist_contains_string(dir_contents, ".."));
+ tt_assert(!smartlist_contains_string(dir_contents, "."));
+ tt_assert(!smartlist_contains_string(dir_contents, ".."));
done:
tor_free(fname1);
@@ -2391,6 +2597,54 @@ test_util_parent_dir(void *ptr)
tor_free(cp);
}
+static void
+test_util_ftruncate(void *ptr)
+{
+ char *buf = NULL;
+ const char *fname;
+ int fd = -1;
+ const char *message = "Hello world";
+ const char *message2 = "Hola mundo";
+ struct stat st;
+
+ (void) ptr;
+
+ fname = get_fname("ftruncate");
+
+ fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT, 0600);
+ tt_int_op(fd, >=, 0);
+
+ /* Make the file be there. */
+ tt_int_op(strlen(message), ==, write_all(fd, message, strlen(message), 0));
+ tt_int_op((int)tor_fd_getpos(fd), ==, strlen(message));
+ tt_int_op(0, ==, fstat(fd, &st));
+ tt_int_op((int)st.st_size, ==, strlen(message));
+
+ /* Truncate and see if it got truncated */
+ tt_int_op(0, ==, tor_ftruncate(fd));
+ tt_int_op((int)tor_fd_getpos(fd), ==, 0);
+ tt_int_op(0, ==, fstat(fd, &st));
+ tt_int_op((int)st.st_size, ==, 0);
+
+ /* Replace, and see if it got replaced */
+ tt_int_op(strlen(message2), ==,
+ write_all(fd, message2, strlen(message2), 0));
+ tt_int_op((int)tor_fd_getpos(fd), ==, strlen(message2));
+ tt_int_op(0, ==, fstat(fd, &st));
+ tt_int_op((int)st.st_size, ==, strlen(message2));
+
+ close(fd);
+ fd = -1;
+
+ buf = read_file_to_str(fname, 0, NULL);
+ tt_str_op(message2, ==, buf);
+
+ done:
+ if (fd >= 0)
+ close(fd);
+ tor_free(buf);
+}
+
#ifdef _WIN32
static void
test_util_load_win_lib(void *ptr)
@@ -2422,30 +2676,53 @@ test_util_exit_status(void *ptr)
(void)ptr;
clear_hex_errno(hex_errno);
+ tt_str_op("",==, hex_errno);
+
+ clear_hex_errno(hex_errno);
n = format_helper_exit_status(0, 0, hex_errno);
- test_streq("0/0\n", hex_errno);
- test_eq(n, strlen(hex_errno));
+ tt_str_op("0/0\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
+
+#if SIZEOF_INT == 4
clear_hex_errno(hex_errno);
n = format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
- test_streq("0/7FFFFFFF\n", hex_errno);
- test_eq(n, strlen(hex_errno));
+ tt_str_op("0/7FFFFFFF\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
clear_hex_errno(hex_errno);
n = format_helper_exit_status(0xFF, -0x80000000, hex_errno);
- test_streq("FF/-80000000\n", hex_errno);
- test_eq(n, strlen(hex_errno));
- test_eq(n, HEX_ERRNO_SIZE);
+ tt_str_op("FF/-80000000\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
+ tt_int_op(n,==, HEX_ERRNO_SIZE);
+
+#elif SIZEOF_INT == 8
+
+ clear_hex_errno(hex_errno);
+ n = format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno);
+ tt_str_op("0/7FFFFFFFFFFFFFFF\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
+
+ clear_hex_errno(hex_errno);
+ n = format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno);
+ tt_str_op("FF/-8000000000000000\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
+ tt_int_op(n,==, HEX_ERRNO_SIZE);
+
+#endif
clear_hex_errno(hex_errno);
n = format_helper_exit_status(0x7F, 0, hex_errno);
- test_streq("7F/0\n", hex_errno);
- test_eq(n, strlen(hex_errno));
+ tt_str_op("7F/0\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
clear_hex_errno(hex_errno);
n = format_helper_exit_status(0x08, -0x242, hex_errno);
- test_streq("8/-242\n", hex_errno);
- test_eq(n, strlen(hex_errno));
+ tt_str_op("8/-242\n",==, hex_errno);
+ tt_int_op(n,==, strlen(hex_errno));
+
+ clear_hex_errno(hex_errno);
+ tt_str_op("",==, hex_errno);
done:
;
@@ -2453,8 +2730,9 @@ test_util_exit_status(void *ptr)
#endif
#ifndef _WIN32
-/** Check that fgets waits until a full line, and not return a partial line, on
- * a EAGAIN with a non-blocking pipe */
+/* Check that fgets with a non-blocking pipe returns partial lines and sets
+ * EAGAIN, returns full lines and sets no error, and returns NULL on EOF and
+ * sets no error */
static void
test_util_fgets_eagain(void *ptr)
{
@@ -2463,17 +2741,19 @@ test_util_fgets_eagain(void *ptr)
ssize_t retlen;
char *retptr;
FILE *test_stream = NULL;
- char buf[10];
+ char buf[4] = { 0 };
(void)ptr;
+ errno = 0;
+
/* Set up a pipe to test on */
retval = pipe(test_pipe);
- tt_int_op(retval, >=, 0);
+ tt_int_op(retval, ==, 0);
/* Set up the read-end to be non-blocking */
retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK);
- tt_int_op(retval, >=, 0);
+ tt_int_op(retval, ==, 0);
/* Open it as a stdio stream */
test_stream = fdopen(test_pipe[0], "r");
@@ -2483,51 +2763,69 @@ test_util_fgets_eagain(void *ptr)
retlen = write(test_pipe[1], "A", 1);
tt_int_op(retlen, ==, 1);
retptr = fgets(buf, sizeof(buf), test_stream);
- tt_want(retptr == NULL);
tt_int_op(errno, ==, EAGAIN);
+ tt_ptr_op(retptr, ==, buf);
+ tt_str_op(buf, ==, "A");
+ errno = 0;
/* Send in the rest */
retlen = write(test_pipe[1], "B\n", 2);
tt_int_op(retlen, ==, 2);
retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_int_op(errno, ==, 0);
tt_ptr_op(retptr, ==, buf);
- tt_str_op(buf, ==, "AB\n");
+ tt_str_op(buf, ==, "B\n");
+ errno = 0;
/* Send in a full line */
retlen = write(test_pipe[1], "CD\n", 3);
tt_int_op(retlen, ==, 3);
retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_int_op(errno, ==, 0);
tt_ptr_op(retptr, ==, buf);
tt_str_op(buf, ==, "CD\n");
+ errno = 0;
/* Send in a partial line */
retlen = write(test_pipe[1], "E", 1);
tt_int_op(retlen, ==, 1);
retptr = fgets(buf, sizeof(buf), test_stream);
- tt_ptr_op(retptr, ==, NULL);
tt_int_op(errno, ==, EAGAIN);
+ tt_ptr_op(retptr, ==, buf);
+ tt_str_op(buf, ==, "E");
+ errno = 0;
/* Send in the rest */
retlen = write(test_pipe[1], "F\n", 2);
tt_int_op(retlen, ==, 2);
retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_int_op(errno, ==, 0);
tt_ptr_op(retptr, ==, buf);
- tt_str_op(buf, ==, "EF\n");
+ tt_str_op(buf, ==, "F\n");
+ errno = 0;
/* Send in a full line and close */
retlen = write(test_pipe[1], "GH", 2);
tt_int_op(retlen, ==, 2);
retval = close(test_pipe[1]);
- test_pipe[1] = -1;
tt_int_op(retval, ==, 0);
+ test_pipe[1] = -1;
retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_int_op(errno, ==, 0);
tt_ptr_op(retptr, ==, buf);
tt_str_op(buf, ==, "GH");
+ errno = 0;
/* Check for EOF */
retptr = fgets(buf, sizeof(buf), test_stream);
+ tt_int_op(errno, ==, 0);
tt_ptr_op(retptr, ==, NULL);
- tt_int_op(feof(test_stream), >, 0);
+ retval = feof(test_stream);
+ tt_int_op(retval, !=, 0);
+ errno = 0;
+
+ /* Check that buf is unchanged according to C99 and C11 */
+ tt_str_op(buf, ==, "GH");
done:
if (test_stream != NULL)
@@ -2552,6 +2850,30 @@ test_util_fgets_eagain(void *ptr)
#define EOL "\n"
#endif
+#ifdef _WIN32
+/* I've assumed Windows doesn't have the gap between fork and exec
+ * that causes the race condition on unix-like platforms */
+#define MATCH_PROCESS_STATUS(s1,s2) ((s1) == (s2))
+
+#else
+/* work around a race condition of the timing of SIGCHLD handler updates
+ * to the process_handle's fields, and checks of those fields
+ *
+ * TODO: Once we can signal failure to exec, change PROCESS_STATUS_RUNNING to
+ * PROCESS_STATUS_ERROR (and similarly with *_OR_NOTRUNNING) */
+#define PROCESS_STATUS_RUNNING_OR_NOTRUNNING (PROCESS_STATUS_RUNNING+1)
+#define IS_RUNNING_OR_NOTRUNNING(s) \
+ ((s) == PROCESS_STATUS_RUNNING || (s) == PROCESS_STATUS_NOTRUNNING)
+/* well, this is ugly */
+#define MATCH_PROCESS_STATUS(s1,s2) \
+ ( (s1) == (s2) \
+ ||((s1) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
+ && IS_RUNNING_OR_NOTRUNNING(s2)) \
+ ||((s2) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
+ && IS_RUNNING_OR_NOTRUNNING(s1)))
+
+#endif // _WIN32
+
/** Helper function for testing tor_spawn_background */
static void
run_util_spawn_background(const char *argv[], const char *expected_out,
@@ -2573,26 +2895,47 @@ run_util_spawn_background(const char *argv[], const char *expected_out,
notify_pending_waitpid_callbacks();
- test_eq(expected_status, status);
+ /* the race condition doesn't affect status,
+ * because status isn't updated by the SIGCHLD handler,
+ * but we still need to handle PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
+ tt_assert(MATCH_PROCESS_STATUS(expected_status, status));
if (status == PROCESS_STATUS_ERROR) {
tt_ptr_op(process_handle, ==, NULL);
return;
}
- test_assert(process_handle != NULL);
- test_eq(expected_status, process_handle->status);
+ tt_assert(process_handle != NULL);
+
+ /* When a spawned process forks, fails, then exits very quickly,
+ * (this typically occurs when exec fails)
+ * there is a race condition between the SIGCHLD handler
+ * updating the process_handle's fields, and this test
+ * checking the process status in those fields.
+ * The SIGCHLD update can occur before or after the code below executes.
+ * This causes intermittent failures in spawn_background_fail(),
+ * typically when the machine is under load.
+ * We use PROCESS_STATUS_RUNNING_OR_NOTRUNNING to avoid this issue. */
+
+ /* the race condition affects the change in
+ * process_handle->status from RUNNING to NOTRUNNING */
+ tt_assert(MATCH_PROCESS_STATUS(expected_status, process_handle->status));
#ifndef _WIN32
notify_pending_waitpid_callbacks();
- tt_ptr_op(process_handle->waitpid_cb, !=, NULL);
+ /* the race condition affects the change in
+ * process_handle->waitpid_cb to NULL,
+ * so we skip the check if expected_status is ambiguous,
+ * that is, PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
+ tt_assert(process_handle->waitpid_cb != NULL
+ || expected_status == PROCESS_STATUS_RUNNING_OR_NOTRUNNING);
#endif
#ifdef _WIN32
- test_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE);
- test_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE);
+ tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE);
+ tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE);
#else
- test_assert(process_handle->stdout_pipe >= 0);
- test_assert(process_handle->stderr_pipe >= 0);
+ tt_assert(process_handle->stdout_pipe >= 0);
+ tt_assert(process_handle->stderr_pipe >= 0);
#endif
/* Check stdout */
@@ -2600,15 +2943,15 @@ run_util_spawn_background(const char *argv[], const char *expected_out,
sizeof(stdout_buf) - 1);
tt_assert(pos >= 0);
stdout_buf[pos] = '\0';
- test_eq(strlen(expected_out), pos);
- test_streq(expected_out, stdout_buf);
+ tt_int_op(strlen(expected_out),==, pos);
+ tt_str_op(expected_out,==, stdout_buf);
notify_pending_waitpid_callbacks();
/* Check it terminated correctly */
retval = tor_get_exit_code(process_handle, 1, &exit_code);
- test_eq(PROCESS_EXIT_EXITED, retval);
- test_eq(expected_exit, exit_code);
+ tt_int_op(PROCESS_EXIT_EXITED,==, retval);
+ tt_int_op(expected_exit,==, exit_code);
// TODO: Make test-child exit with something other than 0
#ifndef _WIN32
@@ -2619,10 +2962,10 @@ run_util_spawn_background(const char *argv[], const char *expected_out,
/* Check stderr */
pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
sizeof(stderr_buf) - 1);
- test_assert(pos >= 0);
+ tt_assert(pos >= 0);
stderr_buf[pos] = '\0';
- test_streq(expected_err, stderr_buf);
- test_eq(strlen(expected_err), pos);
+ tt_str_op(expected_err,==, stderr_buf);
+ tt_int_op(strlen(expected_err),==, pos);
notify_pending_waitpid_callbacks();
@@ -2657,10 +3000,13 @@ test_util_spawn_background_fail(void *ptr)
const int expected_status = PROCESS_STATUS_ERROR;
#else
/* TODO: Once we can signal failure to exec, set this to be
- * PROCESS_STATUS_ERROR */
- const int expected_status = PROCESS_STATUS_RUNNING;
+ * PROCESS_STATUS_RUNNING_OR_ERROR */
+ const int expected_status = PROCESS_STATUS_RUNNING_OR_NOTRUNNING;
#endif
+ memset(expected_out, 0xf0, sizeof(expected_out));
+ memset(code, 0xf0, sizeof(code));
+
(void)ptr;
tor_snprintf(code, sizeof(code), "%x/%x",
@@ -2708,9 +3054,9 @@ test_util_spawn_background_partial_read_impl(int exit_early)
#else
status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
#endif
- test_eq(expected_status, status);
- test_assert(process_handle);
- test_eq(expected_status, process_handle->status);
+ tt_int_op(expected_status,==, status);
+ tt_assert(process_handle);
+ tt_int_op(expected_status,==, process_handle->status);
/* Check stdout */
for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) {
@@ -2719,7 +3065,7 @@ test_util_spawn_background_partial_read_impl(int exit_early)
sizeof(stdout_buf) - 1, NULL);
#else
/* Check that we didn't read the end of file last time */
- test_assert(!eof);
+ tt_assert(!eof);
pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
sizeof(stdout_buf) - 1, NULL, &eof);
#endif
@@ -2729,10 +3075,10 @@ test_util_spawn_background_partial_read_impl(int exit_early)
if (0 == pos)
continue;
- test_assert(pos > 0);
+ tt_assert(pos > 0);
stdout_buf[pos] = '\0';
- test_streq(expected_out[expected_out_ctr], stdout_buf);
- test_eq(strlen(expected_out[expected_out_ctr]), pos);
+ tt_str_op(expected_out[expected_out_ctr],==, stdout_buf);
+ tt_int_op(strlen(expected_out[expected_out_ctr]),==, pos);
expected_out_ctr++;
}
@@ -2747,33 +3093,33 @@ test_util_spawn_background_partial_read_impl(int exit_early)
pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
sizeof(stdout_buf) - 1,
process_handle);
- test_eq(0, pos);
+ tt_int_op(0,==, pos);
#else
if (!eof) {
/* We should have got all the data, but maybe not the EOF flag */
pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
sizeof(stdout_buf) - 1,
process_handle, &eof);
- test_eq(0, pos);
- test_assert(eof);
+ tt_int_op(0,==, pos);
+ tt_assert(eof);
}
/* Otherwise, we got the EOF on the last read */
#endif
/* Check it terminated correctly */
retval = tor_get_exit_code(process_handle, 1, &exit_code);
- test_eq(PROCESS_EXIT_EXITED, retval);
- test_eq(expected_exit, exit_code);
+ tt_int_op(PROCESS_EXIT_EXITED,==, retval);
+ tt_int_op(expected_exit,==, exit_code);
// TODO: Make test-child exit with something other than 0
/* Check stderr */
pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
sizeof(stderr_buf) - 1);
- test_assert(pos >= 0);
+ tt_assert(pos >= 0);
stderr_buf[pos] = '\0';
- test_streq(expected_err, stderr_buf);
- test_eq(strlen(expected_err), pos);
+ tt_str_op(expected_err,==, stderr_buf);
+ tt_int_op(strlen(expected_err),==, pos);
done:
tor_process_handle_destroy(process_handle, 1);
@@ -2848,6 +3194,13 @@ test_util_spawn_background_waitpid_notify(void *arg)
#undef TEST_CHILD
#undef EOL
+#undef MATCH_PROCESS_STATUS
+
+#ifndef _WIN32
+#undef PROCESS_STATUS_RUNNING_OR_NOTRUNNING
+#undef IS_RUNNING_OR_NOTRUNNING
+#endif
+
/**
* Test for format_hex_number_sigsafe()
*/
@@ -2878,15 +3231,15 @@ test_util_format_hex_number(void *ptr)
for (i = 0; test_data[i].str != NULL; ++i) {
len = format_hex_number_sigsafe(test_data[i].x, buf, sizeof(buf));
- test_neq(len, 0);
- test_eq(len, strlen(buf));
- test_streq(buf, test_data[i].str);
+ tt_int_op(len,!=, 0);
+ tt_int_op(len,==, strlen(buf));
+ tt_str_op(buf,==, test_data[i].str);
}
- test_eq(4, format_hex_number_sigsafe(0xffff, buf, 5));
- test_streq(buf, "FFFF");
- test_eq(0, format_hex_number_sigsafe(0xffff, buf, 4));
- test_eq(0, format_hex_number_sigsafe(0, buf, 1));
+ tt_int_op(4,==, format_hex_number_sigsafe(0xffff, buf, 5));
+ tt_str_op(buf,==, "FFFF");
+ tt_int_op(0,==, format_hex_number_sigsafe(0xffff, buf, 4));
+ tt_int_op(0,==, format_hex_number_sigsafe(0, buf, 1));
done:
return;
@@ -2922,21 +3275,21 @@ test_util_format_dec_number(void *ptr)
for (i = 0; test_data[i].str != NULL; ++i) {
len = format_dec_number_sigsafe(test_data[i].x, buf, sizeof(buf));
- test_neq(len, 0);
- test_eq(len, strlen(buf));
- test_streq(buf, test_data[i].str);
+ tt_int_op(len,!=, 0);
+ tt_int_op(len,==, strlen(buf));
+ tt_str_op(buf,==, test_data[i].str);
len = format_dec_number_sigsafe(test_data[i].x, buf,
(int)(strlen(test_data[i].str) + 1));
- test_eq(len, strlen(buf));
- test_streq(buf, test_data[i].str);
+ tt_int_op(len,==, strlen(buf));
+ tt_str_op(buf,==, test_data[i].str);
}
- test_eq(4, format_dec_number_sigsafe(7331, buf, 5));
- test_streq(buf, "7331");
- test_eq(0, format_dec_number_sigsafe(7331, buf, 4));
- test_eq(1, format_dec_number_sigsafe(0, buf, 2));
- test_eq(0, format_dec_number_sigsafe(0, buf, 1));
+ tt_int_op(4,==, format_dec_number_sigsafe(7331, buf, 5));
+ tt_str_op(buf,==, "7331");
+ tt_int_op(0,==, format_dec_number_sigsafe(7331, buf, 4));
+ tt_int_op(1,==, format_dec_number_sigsafe(0, buf, 2));
+ tt_int_op(0,==, format_dec_number_sigsafe(0, buf, 1));
done:
return;
@@ -2985,7 +3338,7 @@ test_util_join_win_cmdline(void *ptr)
for (i=0; cmdlines[i]!=NULL; i++) {
log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]);
joined_argv = tor_join_win_cmdline(argvs[i]);
- test_streq(cmdlines[i], joined_argv);
+ tt_str_op(cmdlines[i],==, joined_argv);
tor_free(joined_argv);
}
@@ -3040,17 +3393,17 @@ test_util_split_lines(void *ptr)
i, tests[i].orig_length);
SMARTLIST_FOREACH_BEGIN(sl, const char *, line) {
/* Check we have not got too many lines */
- test_assert(j < MAX_SPLIT_LINE_COUNT);
+ tt_int_op(MAX_SPLIT_LINE_COUNT, >, j);
/* Check that there actually should be a line here */
- test_assert(tests[i].split_line[j] != NULL);
+ tt_assert(tests[i].split_line[j] != NULL);
log_info(LD_GENERAL, "Line %d of test %d, should be <%s>",
j, i, tests[i].split_line[j]);
/* Check that the line is as expected */
- test_streq(line, tests[i].split_line[j]);
+ tt_str_op(line,==, tests[i].split_line[j]);
j++;
} SMARTLIST_FOREACH_END(line);
/* Check that we didn't miss some lines */
- test_eq_ptr(NULL, tests[i].split_line[j]);
+ tt_ptr_op(NULL,==, tests[i].split_line[j]);
tor_free(orig_line);
smartlist_free(sl);
sl = NULL;
@@ -3062,7 +3415,7 @@ test_util_split_lines(void *ptr)
}
static void
-test_util_di_ops(void)
+test_util_di_ops(void *arg)
{
#define LT -1
#define GT 1
@@ -3082,10 +3435,11 @@ test_util_di_ops(void)
int i;
+ (void)arg;
for (i = 0; examples[i].a; ++i) {
size_t len = strlen(examples[i].a);
int eq1, eq2, neq1, neq2, cmp1, cmp2;
- test_eq(len, strlen(examples[i].b));
+ tt_int_op(len,==, strlen(examples[i].b));
/* We do all of the operations, with operands in both orders. */
eq1 = tor_memeq(examples[i].a, examples[i].b, len);
eq2 = tor_memeq(examples[i].b, examples[i].a, len);
@@ -3096,18 +3450,37 @@ test_util_di_ops(void)
/* Check for correctness of cmp1 */
if (cmp1 < 0 && examples[i].want_sign != LT)
- test_fail();
+ TT_DIE(("Assertion failed."));
else if (cmp1 > 0 && examples[i].want_sign != GT)
- test_fail();
+ TT_DIE(("Assertion failed."));
else if (cmp1 == 0 && examples[i].want_sign != EQ)
- test_fail();
+ TT_DIE(("Assertion failed."));
/* Check for consistency of everything else with cmp1 */
- test_eq(eq1, eq2);
- test_eq(neq1, neq2);
- test_eq(cmp1, -cmp2);
- test_eq(eq1, cmp1 == 0);
- test_eq(neq1, !eq1);
+ tt_int_op(eq1,==, eq2);
+ tt_int_op(neq1,==, neq2);
+ tt_int_op(cmp1,==, -cmp2);
+ tt_int_op(eq1,==, cmp1 == 0);
+ tt_int_op(neq1,==, !eq1);
+ }
+
+ {
+ uint8_t zz = 0;
+ uint8_t ii = 0;
+ int z;
+
+ /* exhaustively test tor_memeq and tor_memcmp
+ * against each possible single-byte numeric difference
+ * some arithmetic bugs only appear with certain bit patterns */
+ for (z = 0; z < 256; z++) {
+ for (i = 0; i < 256; i++) {
+ ii = (uint8_t)i;
+ zz = (uint8_t)z;
+ tt_int_op(tor_memeq(&zz, &ii, 1),==, zz == ii);
+ tt_int_op(tor_memcmp(&zz, &ii, 1) > 0 ? GT : EQ,==, zz > ii ? GT : EQ);
+ tt_int_op(tor_memcmp(&ii, &zz, 1) < 0 ? LT : EQ,==, ii < zz ? LT : EQ);
+ }
+ }
}
tt_int_op(1, ==, safe_mem_is_zero("", 0));
@@ -3131,12 +3504,12 @@ static void
test_util_n_bits_set(void *ptr)
{
(void)ptr;
- test_eq(0, n_bits_set_u8(0));
- test_eq(1, n_bits_set_u8(1));
- test_eq(3, n_bits_set_u8(7));
- test_eq(1, n_bits_set_u8(8));
- test_eq(2, n_bits_set_u8(129));
- test_eq(8, n_bits_set_u8(255));
+ tt_int_op(0,==, n_bits_set_u8(0));
+ tt_int_op(1,==, n_bits_set_u8(1));
+ tt_int_op(3,==, n_bits_set_u8(7));
+ tt_int_op(1,==, n_bits_set_u8(8));
+ tt_int_op(2,==, n_bits_set_u8(129));
+ tt_int_op(8,==, n_bits_set_u8(255));
done:
;
}
@@ -3157,78 +3530,78 @@ test_util_eat_whitespace(void *ptr)
strlcpy(str, "fuubaar", sizeof(str));
for (i = 0; i < sizeof(ws); ++i) {
str[0] = ws[i];
- test_eq_ptr(str + 1, eat_whitespace(str));
- test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str + 1, eat_whitespace_no_nl(str));
- test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+ tt_ptr_op(str + 1,==, eat_whitespace(str));
+ tt_ptr_op(str + 1,==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str + 1,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str + 1,==, eat_whitespace_eos_no_nl(str, str + strlen(str)));
}
str[0] = '\n';
- test_eq_ptr(str + 1, eat_whitespace(str));
- test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str, eat_whitespace_no_nl(str));
- test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+ tt_ptr_op(str + 1,==, eat_whitespace(str));
+ tt_ptr_op(str + 1,==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Empty string */
strlcpy(str, "", sizeof(str));
- test_eq_ptr(str, eat_whitespace(str));
- test_eq_ptr(str, eat_whitespace_eos(str, str));
- test_eq_ptr(str, eat_whitespace_no_nl(str));
- test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str));
+ tt_ptr_op(str,==, eat_whitespace(str));
+ tt_ptr_op(str,==, eat_whitespace_eos(str, str));
+ tt_ptr_op(str,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str));
/* Only ws */
strlcpy(str, " \t\r\n", sizeof(str));
- test_eq_ptr(str + strlen(str), eat_whitespace(str));
- test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str + strlen(str) - 1,
+ tt_ptr_op(str + strlen(str),==, eat_whitespace(str));
+ tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str + strlen(str) - 1,==,
eat_whitespace_no_nl(str));
- test_eq_ptr(str + strlen(str) - 1,
+ tt_ptr_op(str + strlen(str) - 1,==,
eat_whitespace_eos_no_nl(str, str + strlen(str)));
strlcpy(str, " \t\r ", sizeof(str));
- test_eq_ptr(str + strlen(str), eat_whitespace(str));
- test_eq_ptr(str + strlen(str),
+ tt_ptr_op(str + strlen(str),==, eat_whitespace(str));
+ tt_ptr_op(str + strlen(str),==,
eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str + strlen(str), eat_whitespace_no_nl(str));
- test_eq_ptr(str + strlen(str),
+ tt_ptr_op(str + strlen(str),==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str + strlen(str),==,
eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Multiple ws */
strlcpy(str, "fuubaar", sizeof(str));
for (i = 0; i < sizeof(ws); ++i)
str[i] = ws[i];
- test_eq_ptr(str + sizeof(ws), eat_whitespace(str));
- test_eq_ptr(str + sizeof(ws), eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str + sizeof(ws), eat_whitespace_no_nl(str));
- test_eq_ptr(str + sizeof(ws),
+ tt_ptr_op(str + sizeof(ws),==, eat_whitespace(str));
+ tt_ptr_op(str + sizeof(ws),==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str + sizeof(ws),==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str + sizeof(ws),==,
eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Eat comment */
strlcpy(str, "# Comment \n No Comment", sizeof(str));
- test_streq("No Comment", eat_whitespace(str));
- test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str, eat_whitespace_no_nl(str));
- test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+ tt_str_op("No Comment",==, eat_whitespace(str));
+ tt_str_op("No Comment",==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Eat comment & ws mix */
strlcpy(str, " # \t Comment \n\t\nNo Comment", sizeof(str));
- test_streq("No Comment", eat_whitespace(str));
- test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str + 1, eat_whitespace_no_nl(str));
- test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+ tt_str_op("No Comment",==, eat_whitespace(str));
+ tt_str_op("No Comment",==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str + 1,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str + 1,==, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Eat entire comment */
strlcpy(str, "#Comment", sizeof(str));
- test_eq_ptr(str + strlen(str), eat_whitespace(str));
- test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str, eat_whitespace_no_nl(str));
- test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+ tt_ptr_op(str + strlen(str),==, eat_whitespace(str));
+ tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str + strlen(str)));
/* Blank line, then comment */
strlcpy(str, " \t\n # Comment", sizeof(str));
- test_eq_ptr(str + strlen(str), eat_whitespace(str));
- test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
- test_eq_ptr(str + 2, eat_whitespace_no_nl(str));
- test_eq_ptr(str + 2, eat_whitespace_eos_no_nl(str, str + strlen(str)));
+ tt_ptr_op(str + strlen(str),==, eat_whitespace(str));
+ tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str)));
+ tt_ptr_op(str + 2,==, eat_whitespace_no_nl(str));
+ tt_ptr_op(str + 2,==, eat_whitespace_eos_no_nl(str, str + strlen(str)));
done:
;
@@ -3556,12 +3929,12 @@ test_util_round_to_next_multiple_of(void *arg)
{
(void)arg;
- test_assert(round_uint64_to_next_multiple_of(0,1) == 0);
- test_assert(round_uint64_to_next_multiple_of(0,7) == 0);
+ tt_assert(round_uint64_to_next_multiple_of(0,1) == 0);
+ tt_assert(round_uint64_to_next_multiple_of(0,7) == 0);
- test_assert(round_uint64_to_next_multiple_of(99,1) == 99);
- test_assert(round_uint64_to_next_multiple_of(99,7) == 105);
- test_assert(round_uint64_to_next_multiple_of(99,9) == 99);
+ tt_assert(round_uint64_to_next_multiple_of(99,1) == 99);
+ tt_assert(round_uint64_to_next_multiple_of(99,7) == 105);
+ tt_assert(round_uint64_to_next_multiple_of(99,9) == 99);
done:
;
@@ -3588,7 +3961,7 @@ test_util_strclear(void *arg)
}
#define UTIL_LEGACY(name) \
- { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
+ { #name, test_util_ ## name , 0, NULL, NULL }
#define UTIL_TEST(name, flags) \
{ #name, test_util_ ## name, flags, NULL, NULL }
@@ -3783,12 +4156,13 @@ struct testcase_t util_tests[] = {
UTIL_TEST(asprintf, 0),
UTIL_TEST(listdir, 0),
UTIL_TEST(parent_dir, 0),
+ UTIL_TEST(ftruncate, 0),
#ifdef _WIN32
UTIL_TEST(load_win_lib, 0),
#endif
#ifndef _WIN32
UTIL_TEST(exit_status, 0),
- UTIL_TEST(fgets_eagain, TT_SKIP),
+ UTIL_TEST(fgets_eagain, 0),
#endif
UTIL_TEST(spawn_background_ok, 0),
UTIL_TEST(spawn_background_fail, 0),
@@ -3806,7 +4180,10 @@ struct testcase_t util_tests[] = {
UTIL_TEST(make_environment, 0),
UTIL_TEST(set_env_var_in_sl, 0),
UTIL_TEST(read_file_eof_tiny_limit, 0),
+ UTIL_TEST(read_file_eof_one_loop_a, 0),
+ UTIL_TEST(read_file_eof_one_loop_b, 0),
UTIL_TEST(read_file_eof_two_loops, 0),
+ UTIL_TEST(read_file_eof_two_loops_b, 0),
UTIL_TEST(read_file_eof_zero_bytes, 0),
UTIL_TEST(write_chunks_to_file, 0),
UTIL_TEST(mathlog, 0),
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index e799df5cad..fae26ef956 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -134,18 +134,30 @@ parse_commandline(int argc, char **argv)
fprintf(stderr, "No argument to -i\n");
return 1;
}
+ if (identity_key_file) {
+ fprintf(stderr, "Duplicate values for -i\n");
+ return -1;
+ }
identity_key_file = tor_strdup(argv[++i]);
} else if (!strcmp(argv[i], "-s")) {
if (i+1>=argc) {
fprintf(stderr, "No argument to -s\n");
return 1;
}
+ if (signing_key_file) {
+ fprintf(stderr, "Duplicate values for -s\n");
+ return -1;
+ }
signing_key_file = tor_strdup(argv[++i]);
} else if (!strcmp(argv[i], "-c")) {
if (i+1>=argc) {
fprintf(stderr, "No argument to -c\n");
return 1;
}
+ if (certificate_file) {
+ fprintf(stderr, "Duplicate values for -c\n");
+ return -1;
+ }
certificate_file = tor_strdup(argv[++i]);
} else if (!strcmp(argv[i], "-m")) {
if (i+1>=argc) {
diff --git a/src/trunnel/include.am b/src/trunnel/include.am
new file mode 100644
index 0000000000..c7ac1679d0
--- /dev/null
+++ b/src/trunnel/include.am
@@ -0,0 +1,29 @@
+
+noinst_LIBRARIES += \
+ src/trunnel/libor-trunnel.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += \
+ src/trunnel/libor-trunnel-testing.a
+endif
+
+AM_CPPFLAGS += -I$(srcdir)/src/ext/trunnel -I$(srcdir)/src/trunnel
+
+TRUNNELSOURCES = \
+ src/ext/trunnel/trunnel.c \
+ src/trunnel/pwbox.c
+
+TRUNNELHEADERS = \
+ src/ext/trunnel/trunnel.h \
+ src/ext/trunnel/trunnel-impl.h \
+ src/trunnel/trunnel-local.h \
+ src/trunnel/pwbox.h
+
+src_trunnel_libor_trunnel_a_SOURCES = $(TRUNNELSOURCES)
+src_trunnel_libor_trunnel_a_CPPFLAGS = -DTRUNNEL_LOCAL_H $(AM_CPPFLAGS)
+
+src_trunnel_libor_trunnel_testing_a_SOURCES = $(TRUNNELSOURCES)
+src_trunnel_libor_trunnel_testing_a_CPPFLAGS = -DTOR_UNIT_TESTS -DTRUNNEL_LOCAL_H $(AM_CPPFLAGS)
+src_trunnel_libor_trunnel_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS+= $(TRUNNELHEADERS)
diff --git a/src/trunnel/pwbox.c b/src/trunnel/pwbox.c
new file mode 100644
index 0000000000..bfea3ac671
--- /dev/null
+++ b/src/trunnel/pwbox.c
@@ -0,0 +1,515 @@
+/* pwbox.c -- generated by Trunnel v1.2.
+ * https://gitweb.torproject.org/trunnel.git
+ * You probably shouldn't edit this file.
+ */
+#include <stdlib.h>
+#include "trunnel-impl.h"
+
+#include "pwbox.h"
+
+#define TRUNNEL_SET_ERROR_CODE(obj) \
+ do { \
+ (obj)->trunnel_error_code_ = 1; \
+ } while (0)
+
+#if defined(__COVERITY__) || defined(__clang_analyzer__)
+/* If we're runnning a static analysis tool, we don't want it to complain
+ * that some of our remaining-bytes checks are dead-code. */
+int pwbox_deadcode_dummy__ = 0;
+#define OR_DEADCODE_DUMMY || pwbox_deadcode_dummy__
+#else
+#define OR_DEADCODE_DUMMY
+#endif
+
+#define CHECK_REMAINING(nbytes, label) \
+ do { \
+ if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
+ goto label; \
+ } \
+ } while (0)
+
+pwbox_encoded_t *
+pwbox_encoded_new(void)
+{
+ pwbox_encoded_t *val = trunnel_calloc(1, sizeof(pwbox_encoded_t));
+ if (NULL == val)
+ return NULL;
+ val->fixedbytes0 = PWBOX0_CONST0;
+ val->fixedbytes1 = PWBOX0_CONST1;
+ return val;
+}
+
+/** Release all storage held inside 'obj', but do not free 'obj'.
+ */
+static void
+pwbox_encoded_clear(pwbox_encoded_t *obj)
+{
+ (void) obj;
+ TRUNNEL_DYNARRAY_WIPE(&obj->skey_header);
+ TRUNNEL_DYNARRAY_CLEAR(&obj->skey_header);
+ TRUNNEL_DYNARRAY_WIPE(&obj->data);
+ TRUNNEL_DYNARRAY_CLEAR(&obj->data);
+}
+
+void
+pwbox_encoded_free(pwbox_encoded_t *obj)
+{
+ if (obj == NULL)
+ return;
+ pwbox_encoded_clear(obj);
+ trunnel_memwipe(obj, sizeof(pwbox_encoded_t));
+ trunnel_free_(obj);
+}
+
+uint32_t
+pwbox_encoded_get_fixedbytes0(pwbox_encoded_t *inp)
+{
+ return inp->fixedbytes0;
+}
+int
+pwbox_encoded_set_fixedbytes0(pwbox_encoded_t *inp, uint32_t val)
+{
+ if (! ((val == PWBOX0_CONST0))) {
+ TRUNNEL_SET_ERROR_CODE(inp);
+ return -1;
+ }
+ inp->fixedbytes0 = val;
+ return 0;
+}
+uint32_t
+pwbox_encoded_get_fixedbytes1(pwbox_encoded_t *inp)
+{
+ return inp->fixedbytes1;
+}
+int
+pwbox_encoded_set_fixedbytes1(pwbox_encoded_t *inp, uint32_t val)
+{
+ if (! ((val == PWBOX0_CONST1))) {
+ TRUNNEL_SET_ERROR_CODE(inp);
+ return -1;
+ }
+ inp->fixedbytes1 = val;
+ return 0;
+}
+uint8_t
+pwbox_encoded_get_header_len(pwbox_encoded_t *inp)
+{
+ return inp->header_len;
+}
+int
+pwbox_encoded_set_header_len(pwbox_encoded_t *inp, uint8_t val)
+{
+ inp->header_len = val;
+ return 0;
+}
+size_t
+pwbox_encoded_getlen_skey_header(const pwbox_encoded_t *inp)
+{
+ return TRUNNEL_DYNARRAY_LEN(&inp->skey_header);
+}
+
+uint8_t
+pwbox_encoded_get_skey_header(pwbox_encoded_t *inp, size_t idx)
+{
+ return TRUNNEL_DYNARRAY_GET(&inp->skey_header, idx);
+}
+
+int
+pwbox_encoded_set_skey_header(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
+{
+ TRUNNEL_DYNARRAY_SET(&inp->skey_header, idx, elt);
+ return 0;
+}
+int
+pwbox_encoded_add_skey_header(pwbox_encoded_t *inp, uint8_t elt)
+{
+#if SIZE_MAX >= UINT8_MAX
+ if (inp->skey_header.n_ == UINT8_MAX)
+ goto trunnel_alloc_failed;
+#endif
+ TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->skey_header, elt, {});
+ return 0;
+ trunnel_alloc_failed:
+ TRUNNEL_SET_ERROR_CODE(inp);
+ return -1;
+}
+
+uint8_t *
+pwbox_encoded_getarray_skey_header(pwbox_encoded_t *inp)
+{
+ return inp->skey_header.elts_;
+}
+int
+pwbox_encoded_setlen_skey_header(pwbox_encoded_t *inp, size_t newlen)
+{
+ uint8_t *newptr;
+#if UINT8_MAX < SIZE_MAX
+ if (newlen > UINT8_MAX)
+ goto trunnel_alloc_failed;
+#endif
+ newptr = trunnel_dynarray_setlen(&inp->skey_header.allocated_,
+ &inp->skey_header.n_, inp->skey_header.elts_, newlen,
+ sizeof(inp->skey_header.elts_[0]), (trunnel_free_fn_t) NULL,
+ &inp->trunnel_error_code_);
+ if (newptr == NULL)
+ goto trunnel_alloc_failed;
+ inp->skey_header.elts_ = newptr;
+ return 0;
+ trunnel_alloc_failed:
+ TRUNNEL_SET_ERROR_CODE(inp);
+ return -1;
+}
+size_t
+pwbox_encoded_getlen_iv(const pwbox_encoded_t *inp)
+{
+ (void)inp; return 16;
+}
+
+uint8_t
+pwbox_encoded_get_iv(const pwbox_encoded_t *inp, size_t idx)
+{
+ trunnel_assert(idx < 16);
+ return inp->iv[idx];
+}
+
+int
+pwbox_encoded_set_iv(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
+{
+ trunnel_assert(idx < 16);
+ inp->iv[idx] = elt;
+ return 0;
+}
+
+uint8_t *
+pwbox_encoded_getarray_iv(pwbox_encoded_t *inp)
+{
+ return inp->iv;
+}
+size_t
+pwbox_encoded_getlen_data(const pwbox_encoded_t *inp)
+{
+ return TRUNNEL_DYNARRAY_LEN(&inp->data);
+}
+
+uint8_t
+pwbox_encoded_get_data(pwbox_encoded_t *inp, size_t idx)
+{
+ return TRUNNEL_DYNARRAY_GET(&inp->data, idx);
+}
+
+int
+pwbox_encoded_set_data(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
+{
+ TRUNNEL_DYNARRAY_SET(&inp->data, idx, elt);
+ return 0;
+}
+int
+pwbox_encoded_add_data(pwbox_encoded_t *inp, uint8_t elt)
+{
+ TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->data, elt, {});
+ return 0;
+ trunnel_alloc_failed:
+ TRUNNEL_SET_ERROR_CODE(inp);
+ return -1;
+}
+
+uint8_t *
+pwbox_encoded_getarray_data(pwbox_encoded_t *inp)
+{
+ return inp->data.elts_;
+}
+int
+pwbox_encoded_setlen_data(pwbox_encoded_t *inp, size_t newlen)
+{
+ uint8_t *newptr;
+ newptr = trunnel_dynarray_setlen(&inp->data.allocated_,
+ &inp->data.n_, inp->data.elts_, newlen,
+ sizeof(inp->data.elts_[0]), (trunnel_free_fn_t) NULL,
+ &inp->trunnel_error_code_);
+ if (newptr == NULL)
+ goto trunnel_alloc_failed;
+ inp->data.elts_ = newptr;
+ return 0;
+ trunnel_alloc_failed:
+ TRUNNEL_SET_ERROR_CODE(inp);
+ return -1;
+}
+size_t
+pwbox_encoded_getlen_hmac(const pwbox_encoded_t *inp)
+{
+ (void)inp; return 32;
+}
+
+uint8_t
+pwbox_encoded_get_hmac(const pwbox_encoded_t *inp, size_t idx)
+{
+ trunnel_assert(idx < 32);
+ return inp->hmac[idx];
+}
+
+int
+pwbox_encoded_set_hmac(pwbox_encoded_t *inp, size_t idx, uint8_t elt)
+{
+ trunnel_assert(idx < 32);
+ inp->hmac[idx] = elt;
+ return 0;
+}
+
+uint8_t *
+pwbox_encoded_getarray_hmac(pwbox_encoded_t *inp)
+{
+ return inp->hmac;
+}
+const char *
+pwbox_encoded_check(const pwbox_encoded_t *obj)
+{
+ if (obj == NULL)
+ return "Object was NULL";
+ if (obj->trunnel_error_code_)
+ return "A set function failed on this object";
+ if (! (obj->fixedbytes0 == PWBOX0_CONST0))
+ return "Integer out of bounds";
+ if (! (obj->fixedbytes1 == PWBOX0_CONST1))
+ return "Integer out of bounds";
+ if (TRUNNEL_DYNARRAY_LEN(&obj->skey_header) != obj->header_len)
+ return "Length mismatch for skey_header";
+ return NULL;
+}
+
+ssize_t
+pwbox_encoded_encoded_len(const pwbox_encoded_t *obj)
+{
+ ssize_t result = 0;
+
+ if (NULL != pwbox_encoded_check(obj))
+ return -1;
+
+
+ /* Length of u32 fixedbytes0 IN [PWBOX0_CONST0] */
+ result += 4;
+
+ /* Length of u32 fixedbytes1 IN [PWBOX0_CONST1] */
+ result += 4;
+
+ /* Length of u8 header_len */
+ result += 1;
+
+ /* Length of u8 skey_header[header_len] */
+ result += TRUNNEL_DYNARRAY_LEN(&obj->skey_header);
+
+ /* Length of u8 iv[16] */
+ result += 16;
+
+ /* Length of u8 data[] */
+ result += TRUNNEL_DYNARRAY_LEN(&obj->data);
+
+ /* Length of u8 hmac[32] */
+ result += 32;
+ return result;
+}
+int
+pwbox_encoded_clear_errors(pwbox_encoded_t *obj)
+{
+ int r = obj->trunnel_error_code_;
+ obj->trunnel_error_code_ = 0;
+ return r;
+}
+ssize_t
+pwbox_encoded_encode(uint8_t *output, size_t avail, const pwbox_encoded_t *obj)
+{
+ ssize_t result = 0;
+ size_t written = 0;
+ uint8_t *ptr = output;
+ const char *msg;
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+ const ssize_t encoded_len = pwbox_encoded_encoded_len(obj);
+#endif
+ int enforce_avail = 0;
+ const size_t avail_orig = avail;
+
+ if (NULL != (msg = pwbox_encoded_check(obj)))
+ goto check_failed;
+
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+ trunnel_assert(encoded_len >= 0);
+#endif
+
+ /* Encode u32 fixedbytes0 IN [PWBOX0_CONST0] */
+ trunnel_assert(written <= avail);
+ if (avail - written < 4)
+ goto truncated;
+ trunnel_set_uint32(ptr, trunnel_htonl(obj->fixedbytes0));
+ written += 4; ptr += 4;
+
+ /* Encode u32 fixedbytes1 IN [PWBOX0_CONST1] */
+ trunnel_assert(written <= avail);
+ if (avail - written < 4)
+ goto truncated;
+ trunnel_set_uint32(ptr, trunnel_htonl(obj->fixedbytes1));
+ written += 4; ptr += 4;
+
+ /* Encode u8 header_len */
+ trunnel_assert(written <= avail);
+ if (avail - written < 1)
+ goto truncated;
+ trunnel_set_uint8(ptr, (obj->header_len));
+ written += 1; ptr += 1;
+
+ /* Encode u8 skey_header[header_len] */
+ {
+ size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->skey_header);
+ trunnel_assert(obj->header_len == elt_len);
+ trunnel_assert(written <= avail);
+ if (avail - written < elt_len)
+ goto truncated;
+ memcpy(ptr, obj->skey_header.elts_, elt_len);
+ written += elt_len; ptr += elt_len;
+ }
+
+ /* Encode u8 iv[16] */
+ trunnel_assert(written <= avail);
+ if (avail - written < 16)
+ goto truncated;
+ memcpy(ptr, obj->iv, 16);
+ written += 16; ptr += 16;
+ {
+
+ /* Encode u8 data[] */
+ {
+ size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->data);
+ trunnel_assert(written <= avail);
+ if (avail - written < elt_len)
+ goto truncated;
+ memcpy(ptr, obj->data.elts_, elt_len);
+ written += elt_len; ptr += elt_len;
+ }
+ trunnel_assert(written <= avail);
+ if (avail - written < 32)
+ goto truncated;
+ avail = written + 32;
+ enforce_avail = 1;
+ }
+
+ /* Encode u8 hmac[32] */
+ trunnel_assert(written <= avail);
+ if (avail - written < 32) {
+ if (avail_orig - written < 32)
+ goto truncated;
+ else
+ goto check_failed;
+ }
+ memcpy(ptr, obj->hmac, 32);
+ written += 32; ptr += 32;
+
+
+ trunnel_assert(ptr == output + written);
+ if (enforce_avail && avail != written)
+ goto check_failed;
+#ifdef TRUNNEL_CHECK_ENCODED_LEN
+ {
+ trunnel_assert(encoded_len >= 0);
+ trunnel_assert((size_t)encoded_len == written);
+ }
+
+#endif
+
+ return written;
+
+ truncated:
+ result = -2;
+ goto fail;
+ check_failed:
+ (void)msg;
+ result = -1;
+ goto fail;
+ fail:
+ trunnel_assert(result < 0);
+ return result;
+}
+
+/** As pwbox_encoded_parse(), but do not allocate the output object.
+ */
+static ssize_t
+pwbox_encoded_parse_into(pwbox_encoded_t *obj, const uint8_t *input, const size_t len_in)
+{
+ const uint8_t *ptr = input;
+ size_t remaining = len_in;
+ ssize_t result = 0;
+ (void)result;
+
+ /* Parse u32 fixedbytes0 IN [PWBOX0_CONST0] */
+ CHECK_REMAINING(4, truncated);
+ obj->fixedbytes0 = trunnel_ntohl(trunnel_get_uint32(ptr));
+ remaining -= 4; ptr += 4;
+ if (! (obj->fixedbytes0 == PWBOX0_CONST0))
+ goto fail;
+
+ /* Parse u32 fixedbytes1 IN [PWBOX0_CONST1] */
+ CHECK_REMAINING(4, truncated);
+ obj->fixedbytes1 = trunnel_ntohl(trunnel_get_uint32(ptr));
+ remaining -= 4; ptr += 4;
+ if (! (obj->fixedbytes1 == PWBOX0_CONST1))
+ goto fail;
+
+ /* Parse u8 header_len */
+ CHECK_REMAINING(1, truncated);
+ obj->header_len = (trunnel_get_uint8(ptr));
+ remaining -= 1; ptr += 1;
+
+ /* Parse u8 skey_header[header_len] */
+ CHECK_REMAINING(obj->header_len, truncated);
+ TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->skey_header, obj->header_len, {});
+ obj->skey_header.n_ = obj->header_len;
+ memcpy(obj->skey_header.elts_, ptr, obj->header_len);
+ ptr += obj->header_len; remaining -= obj->header_len;
+
+ /* Parse u8 iv[16] */
+ CHECK_REMAINING(16, truncated);
+ memcpy(obj->iv, ptr, 16);
+ remaining -= 16; ptr += 16;
+ {
+ size_t remaining_after;
+ CHECK_REMAINING(32, truncated);
+ remaining_after = 32;
+ remaining = remaining - 32;
+
+ /* Parse u8 data[] */
+ TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->data, remaining, {});
+ obj->data.n_ = remaining;
+ memcpy(obj->data.elts_, ptr, remaining);
+ ptr += remaining; remaining -= remaining;
+ if (remaining != 0)
+ goto fail;
+ remaining = remaining_after;
+ }
+
+ /* Parse u8 hmac[32] */
+ CHECK_REMAINING(32, truncated);
+ memcpy(obj->hmac, ptr, 32);
+ remaining -= 32; ptr += 32;
+ trunnel_assert(ptr + remaining == input + len_in);
+ return len_in - remaining;
+
+ truncated:
+ return -2;
+ trunnel_alloc_failed:
+ return -1;
+ fail:
+ result = -1;
+ return result;
+}
+
+ssize_t
+pwbox_encoded_parse(pwbox_encoded_t **output, const uint8_t *input, const size_t len_in)
+{
+ ssize_t result;
+ *output = pwbox_encoded_new();
+ if (NULL == *output)
+ return -1;
+ result = pwbox_encoded_parse_into(*output, input, len_in);
+ if (result < 0) {
+ pwbox_encoded_free(*output);
+ *output = NULL;
+ }
+ return result;
+}
diff --git a/src/trunnel/pwbox.h b/src/trunnel/pwbox.h
new file mode 100644
index 0000000000..5b170eb45e
--- /dev/null
+++ b/src/trunnel/pwbox.h
@@ -0,0 +1,173 @@
+/* pwbox.h -- generated by by Trunnel v1.2.
+ * https://gitweb.torproject.org/trunnel.git
+ * You probably shouldn't edit this file.
+ */
+#ifndef TRUNNEL_PWBOX_H
+#define TRUNNEL_PWBOX_H
+
+#include <stdint.h>
+#include "trunnel.h"
+
+#define PWBOX0_CONST0 1414484546
+#define PWBOX0_CONST1 1331179568
+#if !defined(TRUNNEL_OPAQUE) && !defined(TRUNNEL_OPAQUE_PWBOX_ENCODED)
+struct pwbox_encoded_st {
+ uint32_t fixedbytes0;
+ uint32_t fixedbytes1;
+ uint8_t header_len;
+ TRUNNEL_DYNARRAY_HEAD(, uint8_t) skey_header;
+ uint8_t iv[16];
+ TRUNNEL_DYNARRAY_HEAD(, uint8_t) data;
+ uint8_t hmac[32];
+ uint8_t trunnel_error_code_;
+};
+#endif
+typedef struct pwbox_encoded_st pwbox_encoded_t;
+/** Return a newly allocated pwbox_encoded with all elements set to
+ * zero.
+ */
+pwbox_encoded_t *pwbox_encoded_new(void);
+/** Release all storage held by the pwbox_encoded in 'victim'. (Do
+ * nothing if 'victim' is NULL.)
+ */
+void pwbox_encoded_free(pwbox_encoded_t *victim);
+/** Try to parse a pwbox_encoded from the buffer in 'input', using up
+ * to 'len_in' bytes from the input buffer. On success, return the
+ * number of bytes consumed and set *output to the newly allocated
+ * pwbox_encoded_t. On failure, return -2 if the input appears
+ * truncated, and -1 if the input is otherwise invalid.
+ */
+ssize_t pwbox_encoded_parse(pwbox_encoded_t **output, const uint8_t *input, const size_t len_in);
+/** Return the number of bytes we expect to need to encode the
+ * pwbox_encoded in 'obj'. On failure, return a negative value. Note
+ * that this value may be an overestimate, and can even be an
+ * underestimate for certain unencodeable objects.
+ */
+ssize_t pwbox_encoded_encoded_len(const pwbox_encoded_t *obj);
+/** Try to encode the pwbox_encoded from 'input' into the buffer at
+ * 'output', using up to 'avail' bytes of the output buffer. On
+ * success, return the number of bytes used. On failure, return -2 if
+ * the buffer was not long enough, and -1 if the input was invalid.
+ */
+ssize_t pwbox_encoded_encode(uint8_t *output, const size_t avail, const pwbox_encoded_t *input);
+/** Check whether the internal state of the pwbox_encoded in 'obj' is
+ * consistent. Return NULL if it is, and a short message if it is not.
+ */
+const char *pwbox_encoded_check(const pwbox_encoded_t *obj);
+/** Clear any errors that were set on the object 'obj' by its setter
+ * functions. Return true iff errors were cleared.
+ */
+int pwbox_encoded_clear_errors(pwbox_encoded_t *obj);
+/** Return the value of the fixedbytes0 field of the pwbox_encoded_t
+ * in 'inp'
+ */
+uint32_t pwbox_encoded_get_fixedbytes0(pwbox_encoded_t *inp);
+/** Set the value of the fixedbytes0 field of the pwbox_encoded_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int pwbox_encoded_set_fixedbytes0(pwbox_encoded_t *inp, uint32_t val);
+/** Return the value of the fixedbytes1 field of the pwbox_encoded_t
+ * in 'inp'
+ */
+uint32_t pwbox_encoded_get_fixedbytes1(pwbox_encoded_t *inp);
+/** Set the value of the fixedbytes1 field of the pwbox_encoded_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int pwbox_encoded_set_fixedbytes1(pwbox_encoded_t *inp, uint32_t val);
+/** Return the value of the header_len field of the pwbox_encoded_t in
+ * 'inp'
+ */
+uint8_t pwbox_encoded_get_header_len(pwbox_encoded_t *inp);
+/** Set the value of the header_len field of the pwbox_encoded_t in
+ * 'inp' to 'val'. Return 0 on success; return -1 and set the error
+ * code on 'inp' on failure.
+ */
+int pwbox_encoded_set_header_len(pwbox_encoded_t *inp, uint8_t val);
+/** Return the length of the dynamic array holding the skey_header
+ * field of the pwbox_encoded_t in 'inp'.
+ */
+size_t pwbox_encoded_getlen_skey_header(const pwbox_encoded_t *inp);
+/** Return the element at position 'idx' of the dynamic array field
+ * skey_header of the pwbox_encoded_t in 'inp'.
+ */
+uint8_t pwbox_encoded_get_skey_header(pwbox_encoded_t *inp, size_t idx);
+/** Change the element at position 'idx' of the dynamic array field
+ * skey_header of the pwbox_encoded_t in 'inp', so that it will hold
+ * the value 'elt'.
+ */
+int pwbox_encoded_set_skey_header(pwbox_encoded_t *inp, size_t idx, uint8_t elt);
+/** Append a new element 'elt' to the dynamic array field skey_header
+ * of the pwbox_encoded_t in 'inp'.
+ */
+int pwbox_encoded_add_skey_header(pwbox_encoded_t *inp, uint8_t elt);
+/** Return a pointer to the variable-length array field skey_header of
+ * 'inp'.
+ */
+uint8_t * pwbox_encoded_getarray_skey_header(pwbox_encoded_t *inp);
+/** Change the length of the variable-length array field skey_header
+ * of 'inp' to 'newlen'.Fill extra elements with 0. Return 0 on
+ * success; return -1 and set the error code on 'inp' on failure.
+ */
+int pwbox_encoded_setlen_skey_header(pwbox_encoded_t *inp, size_t newlen);
+/** Return the (constant) length of the array holding the iv field of
+ * the pwbox_encoded_t in 'inp'.
+ */
+size_t pwbox_encoded_getlen_iv(const pwbox_encoded_t *inp);
+/** Return the element at position 'idx' of the fixed array field iv
+ * of the pwbox_encoded_t in 'inp'.
+ */
+uint8_t pwbox_encoded_get_iv(const pwbox_encoded_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field iv
+ * of the pwbox_encoded_t in 'inp', so that it will hold the value
+ * 'elt'.
+ */
+int pwbox_encoded_set_iv(pwbox_encoded_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 16-element array field iv of 'inp'.
+ */
+uint8_t * pwbox_encoded_getarray_iv(pwbox_encoded_t *inp);
+/** Return the length of the dynamic array holding the data field of
+ * the pwbox_encoded_t in 'inp'.
+ */
+size_t pwbox_encoded_getlen_data(const pwbox_encoded_t *inp);
+/** Return the element at position 'idx' of the dynamic array field
+ * data of the pwbox_encoded_t in 'inp'.
+ */
+uint8_t pwbox_encoded_get_data(pwbox_encoded_t *inp, size_t idx);
+/** Change the element at position 'idx' of the dynamic array field
+ * data of the pwbox_encoded_t in 'inp', so that it will hold the
+ * value 'elt'.
+ */
+int pwbox_encoded_set_data(pwbox_encoded_t *inp, size_t idx, uint8_t elt);
+/** Append a new element 'elt' to the dynamic array field data of the
+ * pwbox_encoded_t in 'inp'.
+ */
+int pwbox_encoded_add_data(pwbox_encoded_t *inp, uint8_t elt);
+/** Return a pointer to the variable-length array field data of 'inp'.
+ */
+uint8_t * pwbox_encoded_getarray_data(pwbox_encoded_t *inp);
+/** Change the length of the variable-length array field data of 'inp'
+ * to 'newlen'.Fill extra elements with 0. Return 0 on success; return
+ * -1 and set the error code on 'inp' on failure.
+ */
+int pwbox_encoded_setlen_data(pwbox_encoded_t *inp, size_t newlen);
+/** Return the (constant) length of the array holding the hmac field
+ * of the pwbox_encoded_t in 'inp'.
+ */
+size_t pwbox_encoded_getlen_hmac(const pwbox_encoded_t *inp);
+/** Return the element at position 'idx' of the fixed array field hmac
+ * of the pwbox_encoded_t in 'inp'.
+ */
+uint8_t pwbox_encoded_get_hmac(const pwbox_encoded_t *inp, size_t idx);
+/** Change the element at position 'idx' of the fixed array field hmac
+ * of the pwbox_encoded_t in 'inp', so that it will hold the value
+ * 'elt'.
+ */
+int pwbox_encoded_set_hmac(pwbox_encoded_t *inp, size_t idx, uint8_t elt);
+/** Return a pointer to the 32-element array field hmac of 'inp'.
+ */
+uint8_t * pwbox_encoded_getarray_hmac(pwbox_encoded_t *inp);
+
+
+#endif
diff --git a/src/trunnel/pwbox.trunnel b/src/trunnel/pwbox.trunnel
new file mode 100644
index 0000000000..10db74b4e5
--- /dev/null
+++ b/src/trunnel/pwbox.trunnel
@@ -0,0 +1,14 @@
+
+const PWBOX0_CONST0 = 0x544f5242; // TORB
+const PWBOX0_CONST1 = 0x4f583030; // OX00
+
+struct pwbox_encoded {
+ u32 fixedbytes0 IN [PWBOX0_CONST0];
+ u32 fixedbytes1 IN [PWBOX0_CONST1];
+ u8 header_len;
+ u8 skey_header[header_len];
+ u8 iv[16];
+ u8 data[..-32];
+ u8 hmac[32];
+};
+
diff --git a/src/trunnel/trunnel-local.h b/src/trunnel/trunnel-local.h
new file mode 100644
index 0000000000..b7c2ab98ef
--- /dev/null
+++ b/src/trunnel/trunnel-local.h
@@ -0,0 +1,18 @@
+
+#ifndef TRUNNEL_LOCAL_H_INCLUDED
+#define TRUNNEL_LOCAL_H_INCLUDED
+
+#include "util.h"
+#include "compat.h"
+#include "crypto.h"
+
+#define trunnel_malloc tor_malloc
+#define trunnel_calloc tor_calloc
+#define trunnel_strdup tor_strdup
+#define trunnel_free_ tor_free_
+#define trunnel_realloc tor_realloc
+#define trunnel_reallocarray tor_reallocarray
+#define trunnel_assert tor_assert
+#define trunnel_memwipe(mem, len) memwipe((mem), 0, (len))
+
+#endif
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 43ccbc59a1..aa29d0ccaf 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -14,8 +14,6 @@
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H
-#define ENABLE_THREADS
-
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H
@@ -86,18 +84,11 @@
#define HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
-#if defined (WINCE)
-#define HAVE_STRLCAT
-#else
#undef HAVE_STRLCAT
-#endif
/* Define to 1 if you have the `strlcpy' function. */
-#if defined (WINCE)
-#define HAVE_STRLCPY
-#else
#undef HAVE_STRLCPY
-#endif
+
/* Define to 1 if you have the `strptime' function. */
#undef HAVE_STRPTIME
@@ -241,7 +232,7 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.2.5.7-rc-dev"
+#define VERSION "0.2.6.0-alpha-dev"